mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-03 20:54:32 +02:00
Merge branch 'feat/support_hp_uarts_wakeup_modes_during_light_sleep' into 'master'
support hp uarts wakeup modes during light sleep See merge request espressif/esp-idf!37730
This commit is contained in:
@@ -67,6 +67,16 @@ typedef struct {
|
||||
*/
|
||||
esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief Clear the UART wakeup configuration.
|
||||
*
|
||||
* This function will clear the UART wakeup behavior and set to its default configuration.
|
||||
*
|
||||
* @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`.
|
||||
*/
|
||||
void uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -13,6 +13,10 @@
|
||||
|
||||
#include "driver/uart_wakeup.h"
|
||||
#include "hal/uart_hal.h"
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
const __attribute__((unused)) static char *TAG = "uart_wakeup";
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE
|
||||
static esp_err_t uart_char_seq_wk_configure(uart_dev_t *hw, const char* phrase)
|
||||
@@ -59,6 +63,26 @@ esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg)
|
||||
// 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);
|
||||
|
||||
#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
|
||||
bool __attribute__((unused)) is_hp_uart = (uart_num < SOC_UART_HP_NUM);
|
||||
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_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);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (cfg->wakeup_mode) {
|
||||
#if SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
|
||||
case UART_WK_MODE_ACTIVE_THRESH:
|
||||
@@ -89,3 +113,18 @@ esp_err_t uart_wakeup_setup(uart_port_t uart_num, const uart_wakeup_cfg_t *cfg)
|
||||
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
void uart_wakeup_clear(uart_port_t uart_num, uart_wakeup_mode_t wakeup_mode)
|
||||
{
|
||||
#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
|
||||
bool __attribute__((unused)) is_hp_uart = (uart_num < SOC_UART_HP_NUM);
|
||||
|
||||
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(ESP_SLEEP_CLOCK_IOMUX, ESP_SLEEP_CLOCK_OPTION_GATE);
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
@@ -10,11 +10,16 @@ if(CONFIG_SOC_UART_SUPPORT_SLEEP_RETENTION AND CONFIG_PM_ENABLE)
|
||||
list(APPEND srcs "test_uart_retention.c")
|
||||
endif()
|
||||
|
||||
# Only if the target support uart wakeup
|
||||
if(CONFIG_SOC_LIGHT_SLEEP_SUPPORTED)
|
||||
list(APPEND srcs "test_hp_uart_wakeup.c")
|
||||
endif()
|
||||
|
||||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(
|
||||
SRCS ${srcs}
|
||||
REQUIRES esp_driver_uart unity esp_psram test_utils esp_driver_gpio esp_pm
|
||||
REQUIRES esp_driver_uart unity esp_psram test_utils esp_driver_gpio esp_pm esp_timer
|
||||
PRIV_INCLUDE_DIRS .
|
||||
WHOLE_ARCHIVE
|
||||
)
|
||||
|
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "driver/uart.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_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/soc_caps.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "test_common.h"
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32P4
|
||||
#define DEFAULT_UART1_TX_IO_NUM U1TXD_GPIO_NUM
|
||||
#define DEFAULT_UART1_RX_IO_NUM U1RXD_GPIO_NUM
|
||||
#elif CONFIG_IDF_TARGET_ESP32
|
||||
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_25
|
||||
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_26
|
||||
#elif CONFIG_IDF_TARGET_ESP32C2
|
||||
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_1
|
||||
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_0
|
||||
#elif CONFIG_IDF_TARGET_ESP32C6
|
||||
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_1
|
||||
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_0
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_4
|
||||
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_5
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_4
|
||||
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_5
|
||||
#elif CONFIG_IDF_TARGET_ESP32C61
|
||||
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_4
|
||||
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_5
|
||||
#elif CONFIG_IDF_TARGET_ESP32C5
|
||||
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_2
|
||||
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_3
|
||||
#endif
|
||||
|
||||
#define MASTER_UART_NUM (1)
|
||||
#define MASTER_UART_TX_IO_NUM DEFAULT_UART1_TX_IO_NUM
|
||||
#define MASTER_UART_RX_IO_NUM DEFAULT_UART1_RX_IO_NUM
|
||||
#define SLAVE_UART_NUM (1)
|
||||
#define SLAVE_UART_TX_IO_NUM DEFAULT_UART1_RX_IO_NUM
|
||||
#define SLAVE_UART_RX_IO_NUM DEFAULT_UART1_TX_IO_NUM
|
||||
#define UART_BAUD_RATE (115200)
|
||||
#define BUF_SIZE (1024)
|
||||
#define TIMER_WAKEUP_TIME_US (5 * 100 * 1000)
|
||||
|
||||
static void force_stdout(void)
|
||||
{
|
||||
fflush(stdout);
|
||||
fsync(fileno(stdout));
|
||||
}
|
||||
|
||||
/* Initialize UART */
|
||||
static esp_err_t uart_initialization(uart_port_param_t *port_param)
|
||||
{
|
||||
uart_port_t uart_num = port_param->port_num;
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = UART_BAUD_RATE,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.source_clk = port_param->default_src_clk,
|
||||
.rx_flow_ctrl_thresh = port_param->rx_flow_ctrl_thresh,
|
||||
};
|
||||
const int uart_tx = port_param->tx_pin_num;
|
||||
const int uart_rx = port_param->rx_pin_num;
|
||||
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_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 20, NULL, 0));
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Configure UART wakeup */
|
||||
static esp_err_t uart_wakeup_config(uart_port_param_t *port_param, uart_wakeup_cfg_t *uart_wakeup_cfg)
|
||||
{
|
||||
/* This function configures the wakeup behavior for a specified UART port based on the provided configuration.
|
||||
* The behavior depends on the selected wakeup mode and additional parameters such as active threshold or
|
||||
* character sequence, if applicable. It is important that the provided configuration matches the capabilities
|
||||
* 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;
|
||||
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.
|
||||
TEST_ESP_OK(uart_wakeup_setup(uart_num, uart_wakeup_cfg));
|
||||
TEST_ESP_OK(esp_sleep_enable_uart_wakeup(uart_num));
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void init_master(void)
|
||||
{
|
||||
uart_port_param_t port_param = {
|
||||
.port_num = MASTER_UART_NUM,
|
||||
#if SOC_UART_SUPPORT_REF_TICK
|
||||
.default_src_clk = UART_SCLK_REF_TICK,
|
||||
#else
|
||||
.default_src_clk = UART_SCLK_XTAL,
|
||||
#endif
|
||||
.tx_pin_num = MASTER_UART_TX_IO_NUM,
|
||||
.rx_pin_num = MASTER_UART_RX_IO_NUM,
|
||||
.rx_flow_ctrl_thresh = 120
|
||||
};
|
||||
TEST_ESP_OK(uart_initialization(&port_param));
|
||||
unity_send_signal("Master Ready");
|
||||
}
|
||||
|
||||
void deinit_master(void)
|
||||
{
|
||||
TEST_ESP_OK(uart_driver_delete(MASTER_UART_NUM));
|
||||
}
|
||||
|
||||
void send_and_verify_recived_data(const char* message, uint8_t length, bool should_wake_up)
|
||||
{
|
||||
unity_wait_for_signal("Slave Ready");
|
||||
force_stdout();
|
||||
|
||||
uart_flush_input(MASTER_UART_NUM);
|
||||
uart_write_bytes(MASTER_UART_NUM, message, length);
|
||||
|
||||
char *data = (char *) malloc(BUF_SIZE);
|
||||
int len = uart_read_bytes(MASTER_UART_NUM, data, (BUF_SIZE - 1), 1000 / portTICK_PERIOD_MS);
|
||||
|
||||
bool wake_up_detected = false;
|
||||
const char *target = "Wakeup OK!";
|
||||
int target_len = 11;
|
||||
bool match = true;
|
||||
if (len > 0) {
|
||||
if (len != target_len) {
|
||||
match = false;
|
||||
} else {
|
||||
for (int i = 0; i < target_len; i++) {
|
||||
if (data[i] != target[i]) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
wake_up_detected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data[len] = '\0'; // Null-terminate the received data
|
||||
|
||||
free(data);
|
||||
|
||||
TEST_ESP_OK(should_wake_up != wake_up_detected);
|
||||
|
||||
}
|
||||
|
||||
static void init_slave(uart_wakeup_cfg_t *wake_up_cfg)
|
||||
{
|
||||
uart_port_param_t port_param = {
|
||||
.port_num = SLAVE_UART_NUM,
|
||||
#if SOC_UART_SUPPORT_REF_TICK
|
||||
.default_src_clk = UART_SCLK_REF_TICK,
|
||||
#else
|
||||
.default_src_clk = UART_SCLK_XTAL,
|
||||
#endif
|
||||
.tx_pin_num = SLAVE_UART_TX_IO_NUM,
|
||||
.rx_pin_num = SLAVE_UART_RX_IO_NUM,
|
||||
.rx_flow_ctrl_thresh = 120
|
||||
};
|
||||
unity_wait_for_signal("Master Ready");
|
||||
TEST_ESP_OK(uart_initialization(&port_param));
|
||||
TEST_ESP_OK(uart_wakeup_config(&port_param, wake_up_cfg));
|
||||
unity_send_signal("Slave Ready");
|
||||
force_stdout();
|
||||
}
|
||||
|
||||
static void deinit_slave(void)
|
||||
{
|
||||
TEST_ESP_OK(uart_driver_delete(SLAVE_UART_NUM));
|
||||
}
|
||||
|
||||
static void enter_sleep_and_send_respond(void)
|
||||
{
|
||||
/* Get timestamp before entering sleep */
|
||||
int64_t t_before_us = esp_timer_get_time();
|
||||
|
||||
/* Enter sleep mode */
|
||||
esp_light_sleep_start();
|
||||
|
||||
/* Get timestamp after waking up from sleep */
|
||||
int64_t t_after_us = esp_timer_get_time();
|
||||
|
||||
uart_flush_input(SLAVE_UART_NUM);
|
||||
printf("sleep duration: %lld\n", t_after_us - t_before_us);
|
||||
switch (esp_sleep_get_wakeup_cause()) {
|
||||
case ESP_SLEEP_WAKEUP_UART:
|
||||
/* Hang-up for a while to switch and execute the uart task
|
||||
* Otherwise the chip may fall sleep again before running uart task */
|
||||
vTaskDelay(1);
|
||||
uart_write_bytes(SLAVE_UART_NUM, "Wakeup OK!", 11);
|
||||
break;
|
||||
default:
|
||||
uart_write_bytes(SLAVE_UART_NUM, "Wakeup failed!", 15);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Wait for uart write finish */
|
||||
uart_wait_tx_idle_polling(SLAVE_UART_NUM);
|
||||
}
|
||||
|
||||
// slave
|
||||
#if SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
|
||||
static void test_uart_wakeup_mode_0(void)
|
||||
{
|
||||
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US));
|
||||
uart_wakeup_cfg_t wake_up_cfg = {
|
||||
.wakeup_mode = UART_WK_MODE_ACTIVE_THRESH,
|
||||
.rx_edge_threshold = 8,
|
||||
};
|
||||
init_slave(&wake_up_cfg);
|
||||
|
||||
enter_sleep_and_send_respond();
|
||||
|
||||
deinit_slave();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_FIFO_THRESH_MODE
|
||||
static void test_uart_wakeup_mode_1(void)
|
||||
{
|
||||
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US));
|
||||
uart_wakeup_cfg_t wake_up_cfg = {
|
||||
.wakeup_mode = UART_WK_MODE_FIFO_THRESH,
|
||||
.rx_fifo_threshold = 8
|
||||
};
|
||||
init_slave(&wake_up_cfg);
|
||||
|
||||
enter_sleep_and_send_respond();
|
||||
|
||||
deinit_slave();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_START_BIT_MODE
|
||||
static void test_uart_wakeup_mode_2(void)
|
||||
{
|
||||
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US));
|
||||
uart_wakeup_cfg_t wake_up_cfg = {
|
||||
.wakeup_mode = UART_WK_MODE_START_BIT,
|
||||
};
|
||||
init_slave(&wake_up_cfg);
|
||||
|
||||
enter_sleep_and_send_respond();
|
||||
|
||||
deinit_slave();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE
|
||||
static void test_uart_wakeup_mode_3(void)
|
||||
{
|
||||
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(TIMER_WAKEUP_TIME_US));
|
||||
uart_wakeup_cfg_t wake_up_cfg = {
|
||||
.wakeup_mode = UART_WK_MODE_CHAR_SEQ,
|
||||
.wake_chars_seq = "hello"
|
||||
};
|
||||
init_slave(&wake_up_cfg);
|
||||
|
||||
enter_sleep_and_send_respond();
|
||||
|
||||
deinit_slave();
|
||||
}
|
||||
#endif
|
||||
|
||||
// master
|
||||
#if SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
|
||||
static void send_uart_wakeup_mode_0_edge_8(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* This is only true in 8N1 mode (8 data bits, no parity, 1 stop bit).
|
||||
* Sending "TT" corresponds to:
|
||||
* +-------+--------------+------+--------+
|
||||
* | Start | Data Bits | Stop | Raises |
|
||||
* +-------+--------------+------+--------+
|
||||
* | 0 | 00101010(T) | 1 | 4 |
|
||||
* | 0 | 00101010(T) | 1 | 4 |
|
||||
* +-------+--------------+------+--------+
|
||||
*/
|
||||
init_master();
|
||||
|
||||
send_and_verify_recived_data("TT", 2, true);
|
||||
|
||||
deinit_master();
|
||||
}
|
||||
|
||||
static void send_uart_wakeup_mode_0_edge_7(void)
|
||||
{
|
||||
/*
|
||||
* This is only true in 8N1 mode (8 data bits, no parity, 1 stop bit).
|
||||
* Sending "Ta" corresponds to:
|
||||
* +-------+--------------+------+--------+
|
||||
* | Start | Data Bits | Stop | Raises |
|
||||
* +-------+--------------+------+--------+
|
||||
* | 0 | 00101010(T) | 1 | 4 |
|
||||
* | 0 | 10000110(a) | 1 | 3 |
|
||||
* +-------+--------------+------+--------+
|
||||
*/
|
||||
init_master();
|
||||
|
||||
send_and_verify_recived_data("Ta", 2, false);
|
||||
|
||||
deinit_master();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_FIFO_THRESH_MODE
|
||||
static void send_uart_wakeup_mode_1_9_bytes(void)
|
||||
{
|
||||
init_master();
|
||||
|
||||
send_and_verify_recived_data("123456789", 9, true);
|
||||
|
||||
deinit_master();
|
||||
}
|
||||
|
||||
static void send_uart_wakeup_mode_1_8_bytes(void)
|
||||
{
|
||||
init_master();
|
||||
|
||||
send_and_verify_recived_data("12345678", 8, false);
|
||||
|
||||
deinit_master();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_START_BIT_MODE
|
||||
static void send_uart_wakeup_mode_2_start_bit(void)
|
||||
{
|
||||
init_master();
|
||||
|
||||
send_and_verify_recived_data("@", 1, true);
|
||||
|
||||
deinit_master();
|
||||
}
|
||||
|
||||
static void send_uart_wakeup_mode_2_no_start_bit(void)
|
||||
{
|
||||
init_master();
|
||||
|
||||
send_and_verify_recived_data("", 0, false);
|
||||
|
||||
deinit_master();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE
|
||||
static void send_uart_wakeup_mode_3_positive_sequence(void)
|
||||
{
|
||||
init_master();
|
||||
|
||||
send_and_verify_recived_data("hello", 5, true);
|
||||
|
||||
deinit_master();
|
||||
}
|
||||
|
||||
static void send_uart_wakeup_mode_3_negative_sequence(void)
|
||||
{
|
||||
init_master();
|
||||
|
||||
send_and_verify_recived_data("hwllo", 5, false);
|
||||
|
||||
deinit_master();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
|
||||
TEST_CASE_MULTIPLE_DEVICES("Mode 0 - Active threshold - 8 - success", "[uart][wakeup][Mode_0][timeout=5]",
|
||||
test_uart_wakeup_mode_0, send_uart_wakeup_mode_0_edge_8);
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("Mode 0 - Active threshold - 8 - fail", "[uart][wakeup][Mode_0][timeout=5]",
|
||||
test_uart_wakeup_mode_0, send_uart_wakeup_mode_0_edge_7);
|
||||
#endif
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_FIFO_THRESH_MODE
|
||||
TEST_CASE_MULTIPLE_DEVICES("Mode 1 - RX FIFO - 9 bytes - success", "[uart][wakeup][Mode_1][timeout=5]",
|
||||
test_uart_wakeup_mode_1, send_uart_wakeup_mode_1_9_bytes);
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("Mode 1 - RX FIFO - 8 bytes- fail", "[uart][wakeup][Mode_1][timeout=5]",
|
||||
test_uart_wakeup_mode_1, send_uart_wakeup_mode_1_8_bytes);
|
||||
#endif
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_START_BIT_MODE
|
||||
TEST_CASE_MULTIPLE_DEVICES("Mode 2 - Start bit sequence - valid data - success", "[uart][wakeup][Mode_2][timeout=5]",
|
||||
test_uart_wakeup_mode_2, send_uart_wakeup_mode_2_start_bit);
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("Mode 2 - Start bit sequence - no data- fail", "[uart][wakeup][Mode_2][timeout=5]",
|
||||
test_uart_wakeup_mode_2, send_uart_wakeup_mode_2_no_start_bit);
|
||||
#endif
|
||||
|
||||
#if SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE
|
||||
TEST_CASE_MULTIPLE_DEVICES("Mode 3 - Wakeup sequence - positive hello - success", "[uart][wakeup][Mode_3][timeout=5]",
|
||||
test_uart_wakeup_mode_3, send_uart_wakeup_mode_3_positive_sequence);
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("Mode 3 - Wakeup sequence - negative hello- fail", "[uart][wakeup][Mode_3][timeout=5]",
|
||||
test_uart_wakeup_mode_3, send_uart_wakeup_mode_3_negative_sequence);
|
||||
#endif
|
@@ -1,6 +1,7 @@
|
||||
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded_idf import CaseTester
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
input_argv = {
|
||||
@@ -36,7 +37,7 @@ def test_uart_single_dev(case_tester) -> None: # type: ignore
|
||||
assert uart_ports, f"Error: Chip type '{chip_type}' is not defined in input_argv. Aborting..."
|
||||
|
||||
for case in case_tester.test_menu:
|
||||
if 'hp-uart-only' not in case.groups:
|
||||
if 'hp-uart-only' not in case.groups and 'wakeup' not in case.groups:
|
||||
for uart_port in uart_ports:
|
||||
dut.serial.hard_reset()
|
||||
dut._get_ready()
|
||||
@@ -45,7 +46,7 @@ def test_uart_single_dev(case_tester) -> None: # type: ignore
|
||||
dut.expect("select to test 'uart' or 'lp_uart' port", timeout=10)
|
||||
dut.write(f'{uart_port}')
|
||||
dut.expect_unity_test_output()
|
||||
else:
|
||||
elif 'wakeup' not in case.groups:
|
||||
dut._run_normal_case(case, reset=True)
|
||||
|
||||
|
||||
@@ -62,10 +63,30 @@ def test_uart_single_dev(case_tester) -> None: # type: ignore
|
||||
def test_uart_single_dev_psram(case_tester) -> None: # type: ignore
|
||||
dut = case_tester.first_dut
|
||||
for case in case_tester.test_menu:
|
||||
dut.serial.hard_reset()
|
||||
dut._get_ready()
|
||||
dut.confirm_write(case.index, expect_str=f'Running {case.name}...')
|
||||
if 'wakeup' not in case.groups:
|
||||
dut.serial.hard_reset()
|
||||
dut._get_ready()
|
||||
dut.confirm_write(case.index, expect_str=f'Running {case.name}...')
|
||||
|
||||
dut.expect("select to test 'uart' or 'lp_uart' port", timeout=10)
|
||||
dut.write('uart')
|
||||
dut.expect_unity_test_output()
|
||||
dut.expect("select to test 'uart' or 'lp_uart' port", timeout=10)
|
||||
dut.write('uart')
|
||||
dut.expect_unity_test_output()
|
||||
|
||||
|
||||
# ESP32 only supports uart wakeup if signal routes through IOMUX, ESP32S3 multi device runner has no psram IDF-12837,
|
||||
# ESP32C61 lack of runner IDF-10949, ESP32P4 not yet supported IDF-12839.
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32', 'esp32s3', 'esp32c61', 'esp32p4'], reason='no multi-dev runner')
|
||||
@pytest.mark.generic_multi_device
|
||||
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'release',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@pytest.mark.parametrize('count', [2], indirect=True)
|
||||
def test_hp_uart_wakeup_modes(case_tester: CaseTester) -> None:
|
||||
relevant_cases = [case for case in case_tester.test_menu if {'wakeup', 'uart'}.issubset(case.groups)]
|
||||
for case in relevant_cases:
|
||||
case_tester.run_multi_dev_case(case=case, reset=True)
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -86,9 +86,15 @@ typedef enum {
|
||||
#if SOC_UART_SUPPORT_WAKEUP_INT
|
||||
#define RTC_UART0_TRIG_EN PMU_UART0_WAKEUP_EN //!< UART0 wakeup (light sleep only)
|
||||
#define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only)
|
||||
#if SOC_UART_HP_NUM > 2
|
||||
#define RTC_UART2_TRIG_EN PMU_UART2_WAKEUP_EN //!< UART2 wakeup (light sleep only)
|
||||
#else
|
||||
#define RTC_UART2_TRIG_EN 0
|
||||
#endif
|
||||
#else
|
||||
#define RTC_UART0_TRIG_EN 0
|
||||
#define RTC_UART1_TRIG_EN 0
|
||||
#define RTC_UART2_TRIG_EN 0
|
||||
#endif
|
||||
|
||||
#if SOC_BT_SUPPORTED
|
||||
@@ -130,6 +136,7 @@ typedef enum {
|
||||
RTC_WIFI_TRIG_EN | \
|
||||
RTC_UART0_TRIG_EN | \
|
||||
RTC_UART1_TRIG_EN | \
|
||||
RTC_UART2_TRIG_EN | \
|
||||
RTC_BT_TRIG_EN | \
|
||||
RTC_LP_CORE_TRIG_EN | \
|
||||
RTC_TOUCH_TRIG_EN | \
|
||||
|
@@ -92,6 +92,9 @@ typedef enum {
|
||||
ESP_SLEEP_CLOCK_LEDC, //!< The clock ICG cell mapping of LEDC
|
||||
ESP_SLEEP_CLOCK_UART0, //!< The clock ICG cell mapping of UART0
|
||||
ESP_SLEEP_CLOCK_UART1, //!< The clock ICG cell mapping of UART1
|
||||
#if SOC_UART_HP_NUM > 2
|
||||
ESP_SLEEP_CLOCK_UART2, //!< The clock ICG cell mapping of UART2
|
||||
#endif
|
||||
ESP_SLEEP_CLOCK_MAX //!< Number of ICG cells
|
||||
} esp_sleep_clock_t;
|
||||
|
||||
|
@@ -18,6 +18,7 @@ extern "C" {
|
||||
#define PMU_WIFI_SOC_WAKEUP_EN BIT(5)
|
||||
#define PMU_UART0_WAKEUP_EN BIT(6)
|
||||
#define PMU_UART1_WAKEUP_EN BIT(7)
|
||||
#define PMU_UART2_WAKEUP_EN BIT(9)
|
||||
#define PMU_BLE_SOC_WAKEUP_EN BIT(10)
|
||||
// #define PMU_LP_CORE_WAKEUP_EN BIT(11)
|
||||
#define PMU_USB_WAKEUP_EN BIT(14)
|
||||
|
@@ -1644,9 +1644,15 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
|
||||
#endif
|
||||
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_GPIO, RTC_GPIO_TRIG_EN)) {
|
||||
s_config.wakeup_triggers &= ~RTC_GPIO_TRIG_EN;
|
||||
#if SOC_PMU_SUPPORTED && (SOC_UART_HP_NUM > 2)
|
||||
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN | RTC_UART2_TRIG_EN))) {
|
||||
s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN | RTC_UART2_TRIG_EN);
|
||||
}
|
||||
#else
|
||||
} else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) {
|
||||
s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN);
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_ULP_COPROC_TYPE_FSM
|
||||
else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
|
||||
s_config.wakeup_triggers &= ~RTC_ULP_TRIG_EN;
|
||||
@@ -2125,6 +2131,10 @@ esp_err_t esp_sleep_enable_uart_wakeup(int uart_num)
|
||||
s_config.wakeup_triggers |= RTC_UART0_TRIG_EN;
|
||||
} else if (uart_num == UART_NUM_1) {
|
||||
s_config.wakeup_triggers |= RTC_UART1_TRIG_EN;
|
||||
#if SOC_PMU_SUPPORTED && (SOC_UART_HP_NUM > 2)
|
||||
} else if (uart_num == UART_NUM_2) {
|
||||
s_config.wakeup_triggers |= RTC_UART2_TRIG_EN;
|
||||
#endif
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@@ -2208,7 +2218,11 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void)
|
||||
return ESP_SLEEP_WAKEUP_TIMER;
|
||||
} else if (wakeup_cause & RTC_GPIO_TRIG_EN) {
|
||||
return ESP_SLEEP_WAKEUP_GPIO;
|
||||
#if SOC_PMU_SUPPORTED && (SOC_UART_HP_NUM > 2)
|
||||
} else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN | RTC_UART2_TRIG_EN)) {
|
||||
#else
|
||||
} else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) {
|
||||
#endif
|
||||
return ESP_SLEEP_WAKEUP_UART;
|
||||
#if SOC_PM_SUPPORT_EXT0_WAKEUP
|
||||
} else if (wakeup_cause & RTC_EXT0_TRIG_EN) {
|
||||
@@ -2614,6 +2628,11 @@ static SLEEP_FN_ATTR uint32_t get_sleep_clock_icg_flags(void)
|
||||
if (s_config.clock_icg_refs[ESP_SLEEP_CLOCK_UART1] > 0) {
|
||||
clk_flags |= BIT(PMU_ICG_FUNC_ENA_UART1);
|
||||
}
|
||||
#if SOC_UART_HP_NUM > 2
|
||||
if (s_config.clock_icg_refs[ESP_SLEEP_CLOCK_UART2] > 0) {
|
||||
clk_flags |= BIT(PMU_ICG_FUNC_ENA_UART2);
|
||||
}
|
||||
#endif
|
||||
#endif /* SOC_PM_SUPPORT_PMU_CLK_ICG */
|
||||
return clk_flags;
|
||||
}
|
||||
|
@@ -30,6 +30,8 @@ extern "C" {
|
||||
#define LP_UART_LL_FIFO_DEF_LEN (SOC_LP_UART_FIFO_LEN)
|
||||
// Get UART hardware instance with giving uart num
|
||||
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&LP_UART)))
|
||||
// Get UART sleep clock with giving uart num
|
||||
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (ESP_SLEEP_CLOCK_UART1))
|
||||
|
||||
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
|
||||
|
||||
|
@@ -30,6 +30,8 @@ extern "C" {
|
||||
#define LP_UART_LL_FIFO_DEF_LEN (SOC_LP_UART_FIFO_LEN)
|
||||
// Get UART hardware instance with giving uart num
|
||||
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&LP_UART)))
|
||||
// Get UART sleep clock with giving uart num
|
||||
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (ESP_SLEEP_CLOCK_UART1))
|
||||
|
||||
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
|
||||
|
||||
|
@@ -29,6 +29,8 @@ extern "C" {
|
||||
#define UART_LL_FIFO_DEF_LEN (SOC_UART_FIFO_LEN)
|
||||
// Get UART hardware instance with giving uart num
|
||||
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (((num) == UART_NUM_1) ? (&UART1) : (&UART2)))
|
||||
// Get UART sleep clock with giving uart num
|
||||
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (((num) == UART_NUM_1) ? (ESP_SLEEP_CLOCK_UART1) : (ESP_SLEEP_CLOCK_UART2)))
|
||||
|
||||
#define UART_LL_PULSE_TICK_CNT_MAX UART_LOWPULSE_MIN_CNT_V
|
||||
|
||||
|
@@ -28,6 +28,8 @@ extern "C" {
|
||||
#define UART_LL_FIFO_DEF_LEN (SOC_UART_FIFO_LEN)
|
||||
// Get UART hardware instance with giving uart num
|
||||
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (&UART1))
|
||||
// Get UART sleep clock with giving uart num
|
||||
#define UART_LL_SLEEP_CLOCK(num) (((num) == UART_NUM_0) ? (ESP_SLEEP_CLOCK_UART0) : (ESP_SLEEP_CLOCK_UART1))
|
||||
|
||||
#define UART_LL_PULSE_TICK_CNT_MAX UART_LOWPULSE_MIN_CNT_V
|
||||
|
||||
|
33
examples/system/light_sleep/main/Kconfig.projbuild
Normal file
33
examples/system/light_sleep/main/Kconfig.projbuild
Normal file
@@ -0,0 +1,33 @@
|
||||
menu "Example Configuration"
|
||||
|
||||
choice EXAMPLE_UART_WAKEUP_MODE
|
||||
prompt "uart wakeup mode"
|
||||
default UART_WK_MODE_ACTIVE_THRESH
|
||||
help
|
||||
Uart wakeup MODE_ACTIVE_THRESH | MODE_FIFO_THRESH | MODE_START_BIT | MODE_CHAR_SEQ to be selected
|
||||
for uart wakeup during light sleep. Specifically, wakeup MODE_ACTIVE_THRESH doesn't require a clock.
|
||||
In contrast, the other three wakeup modes need XTAL (not RC FAST for instability) ungated during light
|
||||
sleep, where the chips used should support sleep clock icg control. However, they consume more power
|
||||
as XTAL must be powered on.
|
||||
|
||||
config UART_WK_MODE_ACTIVE_THRESH
|
||||
bool "MODE_ACTIVE_THRESH"
|
||||
config UART_WK_MODE_FIFO_THRESH
|
||||
bool "MODE_FIFO_THRESH"
|
||||
depends on SOC_UART_WAKEUP_SUPPORT_FIFO_THRESH_MODE && SOC_PM_SUPPORT_PMU_CLK_ICG && SOC_PMU_SUPPORTED
|
||||
config UART_WK_MODE_START_BIT
|
||||
bool "MODE_START_BIT"
|
||||
depends on SOC_UART_WAKEUP_SUPPORT_START_BIT_MODE && SOC_PM_SUPPORT_PMU_CLK_ICG && SOC_PMU_SUPPORTED
|
||||
config UART_WK_MODE_CHAR_SEQ
|
||||
bool "MODE_CHAR_SEQ"
|
||||
depends on SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE && SOC_PM_SUPPORT_PMU_CLK_ICG && SOC_PMU_SUPPORTED
|
||||
endchoice
|
||||
|
||||
config EXAMPLE_UART_WAKEUP_MODE_SELCTED
|
||||
int
|
||||
default 0 if UART_WK_MODE_ACTIVE_THRESH
|
||||
default 1 if UART_WK_MODE_FIFO_THRESH
|
||||
default 2 if UART_WK_MODE_START_BIT
|
||||
default 3 if UART_WK_MODE_CHAR_SEQ
|
||||
|
||||
endmenu
|
@@ -1,14 +1,17 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "soc/uart_pins.h"
|
||||
#include "driver/uart.h"
|
||||
#include "driver/uart_wakeup.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
@@ -18,7 +21,10 @@
|
||||
#define EXAMPLE_UART_TX_IO_NUM U0TXD_GPIO_NUM
|
||||
#define EXAMPLE_UART_RX_IO_NUM U0RXD_GPIO_NUM
|
||||
|
||||
#define EXAMPLE_UART_WAKEUP_THRESHOLD 3
|
||||
#define EXAMPLE_UART_WAKEUP_EDGE_THRESHOLD 3
|
||||
#define EXAMPLE_UART_WAKEUP_FIFO_THRESHOLD 8
|
||||
#define EXAMPLE_UART_WAKEUP_CHARS_SEQ "ok"
|
||||
#define EXAMPLE_UART_WAKEUP_CHARS_SEQ_LEN SOC_UART_WAKEUP_CHARS_SEQ_MAX_LEN
|
||||
|
||||
#define EXAMPLE_READ_BUF_SIZE 1024
|
||||
#define EXAMPLE_UART_BUF_SIZE (EXAMPLE_READ_BUF_SIZE * 2)
|
||||
@@ -123,12 +129,45 @@ static esp_err_t uart_initialization(void)
|
||||
|
||||
static esp_err_t uart_wakeup_config(void)
|
||||
{
|
||||
/* UART will wakeup the chip up from light sleep if the edges that RX pin received has reached the threshold */
|
||||
ESP_RETURN_ON_ERROR(uart_set_wakeup_threshold(EXAMPLE_UART_NUM, EXAMPLE_UART_WAKEUP_THRESHOLD),
|
||||
TAG, "Set uart wakeup threshold failed");
|
||||
/* Only uart0 and uart1 (if has) support to be configured as wakeup source */
|
||||
ESP_RETURN_ON_ERROR(esp_sleep_enable_uart_wakeup(EXAMPLE_UART_NUM),
|
||||
TAG, "Configure uart as wakeup source failed");
|
||||
uart_wakeup_cfg_t uart_wakeup_cfg = {};
|
||||
uint8_t wakeup_mode = CONFIG_EXAMPLE_UART_WAKEUP_MODE_SELCTED;
|
||||
switch (wakeup_mode) {
|
||||
/* UART will wakeup the chip up from light sleep if the edges that RX pin received reaches the threshold */
|
||||
#if SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE
|
||||
case UART_WK_MODE_ACTIVE_THRESH:
|
||||
uart_wakeup_cfg.wakeup_mode = UART_WK_MODE_ACTIVE_THRESH;
|
||||
uart_wakeup_cfg.rx_edge_threshold = EXAMPLE_UART_WAKEUP_EDGE_THRESHOLD;
|
||||
break;
|
||||
#endif
|
||||
/* UART will wakeup the chip up from light sleep if the number of chars that RX FIFO received reaches the threshold */
|
||||
#if SOC_UART_WAKEUP_SUPPORT_FIFO_THRESH_MODE
|
||||
case UART_WK_MODE_FIFO_THRESH:
|
||||
uart_wakeup_cfg.wakeup_mode = UART_WK_MODE_FIFO_THRESH;
|
||||
uart_wakeup_cfg.rx_fifo_threshold = EXAMPLE_UART_WAKEUP_FIFO_THRESHOLD;
|
||||
break;
|
||||
#endif
|
||||
/* UART will wakeup the chip up from light sleep if RX FIFO receives a start bit */
|
||||
#if SOC_UART_WAKEUP_SUPPORT_START_BIT_MODE
|
||||
case UART_WK_MODE_START_BIT:
|
||||
uart_wakeup_cfg.wakeup_mode = UART_WK_MODE_START_BIT;
|
||||
break;
|
||||
#endif
|
||||
/* UART will wakeup the chip up from light sleep if the chars sequence that RX FIFO received matches the predefined value */
|
||||
#if SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE
|
||||
case UART_WK_MODE_CHAR_SEQ:
|
||||
uart_wakeup_cfg.wakeup_mode = UART_WK_MODE_CHAR_SEQ;
|
||||
// uart wakeup chars len need less than SOC_UART_WAKEUP_CHARS_SEQ_MAX_LEN
|
||||
strncpy(uart_wakeup_cfg.wake_chars_seq, EXAMPLE_UART_WAKEUP_CHARS_SEQ, EXAMPLE_UART_WAKEUP_CHARS_SEQ_LEN);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ESP_LOGE(TAG, "Unknown UART wakeup mode");
|
||||
return ESP_FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_ERROR_CHECK(uart_wakeup_setup(EXAMPLE_UART_NUM, &uart_wakeup_cfg));
|
||||
ESP_ERROR_CHECK(esp_sleep_enable_uart_wakeup(EXAMPLE_UART_NUM));
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user