fix(uart): Fix mismatch wakeup rising edges required with the threshold configured

Closes https://github.com/espressif/esp-idf/issues/12586
pull/13306/head^2
Song Ruo Jing 2024-03-07 16:59:20 +08:00
rodzic 3cd174ab09
commit 90bf2772ac
14 zmienionych plików z 34 dodań i 18 usunięć

Wyświetl plik

@ -1792,7 +1792,7 @@ esp_err_t uart_get_collision_flag(uart_port_t uart_num, bool *collision_flag)
esp_err_t uart_set_wakeup_threshold(uart_port_t uart_num, int wakeup_threshold)
{
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_ERR_INVALID_ARG, UART_TAG, "uart_num error");
ESP_RETURN_ON_FALSE((wakeup_threshold <= UART_THRESHOLD_NUM(uart_num, UART_ACTIVE_THRESHOLD_V) && wakeup_threshold > UART_MIN_WAKEUP_THRESH), ESP_ERR_INVALID_ARG, UART_TAG,
ESP_RETURN_ON_FALSE((wakeup_threshold <= UART_THRESHOLD_NUM(uart_num, UART_ACTIVE_THRESHOLD_V) && wakeup_threshold >= UART_MIN_WAKEUP_THRESH), ESP_ERR_INVALID_ARG, UART_TAG,
"wakeup_threshold out of bounds");
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
uart_hal_set_wakeup_thrd(&(uart_context[uart_num].hal), wakeup_threshold);

Wyświetl plik

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -30,7 +30,7 @@ extern "C" {
// The timeout calibration factor when using ref_tick
#define UART_LL_TOUT_REF_FACTOR_DEFAULT (8)
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
// Define UART interrupts
@ -692,7 +692,9 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+2)
// Note: On ESP32, the minimum UART wakeup threshold is 2 + 1 = 3 (UART_ACTIVE_THRESHOLD set to 0 leads to consecutive triggering wakeup)
hw->sleep_conf.active_threshold = wakeup_thrd - (UART_LL_MIN_WAKEUP_THRESH - 1);
}
/**
@ -834,7 +836,7 @@ FORCE_INLINE_ATTR void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char
*/
FORCE_INLINE_ATTR uint32_t uart_ll_get_wakeup_thrd(uart_dev_t *hw)
{
return hw->sleep_conf.active_threshold + UART_LL_MIN_WAKEUP_THRESH;
return hw->sleep_conf.active_threshold + (UART_LL_MIN_WAKEUP_THRESH - 1);
}
/**

Wyświetl plik

@ -29,7 +29,7 @@ extern "C" {
// Get UART hardware instance with giving uart num
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (&UART1))
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define UART_LL_FSM_IDLE (0x0)
@ -675,6 +675,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -29,7 +29,7 @@ extern "C" {
// Get UART hardware instance with giving uart num
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (&UART1))
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define UART_LL_FSM_IDLE (0x0)
@ -678,6 +678,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -34,7 +34,7 @@ extern "C" {
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define UART_LL_FSM_IDLE (0x0)
@ -897,6 +897,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -33,7 +33,7 @@ extern "C" {
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define UART_LL_FSM_IDLE (0x0)
@ -867,6 +867,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -29,7 +29,7 @@ extern "C" {
// Get UART hardware instance with giving uart num
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (&UART1))
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define UART_LL_FSM_IDLE (0x0)
@ -717,6 +717,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -39,7 +39,7 @@ extern "C" {
#define UART_LL_REG_FIELD_BIT_SHIFT(hw) (((hw) == &LP_UART) ? 3 : 0)
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define UART_LL_FSM_IDLE (0x0)
@ -980,6 +980,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -28,7 +28,7 @@ extern "C" {
// Get UART hardware instance with giving uart num
#define UART_LL_GET_HW(num) (((num) == UART_NUM_0) ? (&UART0) : (&UART1))
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
// Define UART interrupts
@ -633,6 +633,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -29,7 +29,7 @@ extern "C" {
// 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)))
#define UART_LL_MIN_WAKEUP_THRESH (2)
#define UART_LL_MIN_WAKEUP_THRESH (3)
#define UART_LL_INTR_MASK (0x7ffff) //All interrupt mask
#define UART_LL_FSM_IDLE (0x0)
@ -661,6 +661,7 @@ FORCE_INLINE_ATTR void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level)
*/
FORCE_INLINE_ATTR void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd)
{
// System would wakeup when the number of positive edges of RxD signal is larger than or equal to (UART_ACTIVE_THRESHOLD+3)
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
}

Wyświetl plik

@ -326,6 +326,8 @@ When {IDF_TARGET_NAME} receives UART input from external devices, it is often ne
:cpp:func:`esp_sleep_enable_uart_wakeup` function can be used to enable this wakeup source.
After waking-up from UART, you should send some extra data through the UART port in Active mode, so that the internal wakeup indication signal can be cleared. Otherwises, the next UART wake-up would trigger with two less rising edges than the configured threshold value.
.. only:: esp32c6 or esp32h2
.. note::

Wyświetl plik

@ -326,6 +326,8 @@ UART 唤醒(仅适用于 Light-sleep 模式)
可调用 :cpp:func:`esp_sleep_enable_uart_wakeup` 函数来启用此唤醒源。
使用 UART 唤醒之后,在芯片 Active 模式下需要让 UART 接受一些数据用来清零内部的唤醒指示信号。不然的话,下一次 UART 唤醒的触发将只需要比配置的阈值少两个上升沿的数量。
.. only:: esp32c6 or esp32h2
.. note::

Wyświetl plik

@ -11,7 +11,7 @@ The example enables the following wakeup sources:
- Timer: wake up the chip in 2 seconds
- EXT0: wake up the chip if a button attached to GPIO0 is pressed (i.e. if GPIO0 goes low)
- UART0: wake up the chip when the uart rx pin (default GPIO6) receive more than 3 edges.
- UART0: wake up the chip when the uart rx pin receive more than or equal to 3 rising edges.
The example also prints time spent in light sleep mode to illustrate that timekeeping continues while the chip is in light sleep.
@ -60,12 +60,14 @@ For this example, the wake-up GPIO is bound to the 'BOOT' button on the board, w
For this example, the wake-up UART is bound to the default console port (UART_NUM_0), we can wake-up the chip from light sleep by inputting some keys on the key board. We can see the wake-up reason is `uart` in this case.
Note #1: the UART wake-up threshould is set to 3 in this example, which means the ascii code of the input character should has at least 3 edges, for example, the ascii code of character `0` is `0011 0000` in binary, which only contains 2 edges, so the character `0` is not enough to wakeup the chip.
Note #1: the UART wake-up threshould is set to 3 in this example, which means the ascii code of the input character to wake-up the chip should has at least 3 rising edges (including the stop bit per character), for example, the ascii code of character `0` is `0011 0000` in binary, which only contains 2 rising edges, so the character `0` is not enough to wakeup the chip.
Note #2: only UART0 and UART1 (if has) are supported to be configured as wake up source. And for ESP32, we have to use iomux pin for RX signal (i.e. GPIO3 for UART0 & GPIO9 for UART1), otherwise it won't success.
Note #3: due to limitation of the HW, the bytes that received during light sleep is only used for waking up, and it will not be received by UART peripheral or passed to the driver.
Note #4: after waking-up from UART, you should send some extra data through the UART port, so that the internal wakeup indication signal can be cleared. Otherwises, the next UART wake-up would trigger with two less rising edges than the configured threshold value.
### Wake-up by Touch Pad
For this example, pressing any registered touch buttons can wake up the chip.

Wyświetl plik

@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import logging
import time
@ -52,8 +52,8 @@ def test_light_sleep(dut: Dut) -> None:
dut.expect_exact(ENTERING_SLEEP_STR)
logging.info('Went to sleep again')
# Write 'U' to uart, 'U' in ascii is 0x55 which contains 8 edges in total
dut.write('U')
# Write 'a' to uart, 'a' in ascii is 0x61 which contains 3 rising edges in total (including the stop bit)
dut.write('a')
time.sleep(1)
match = dut.expect(EXIT_SLEEP_UART_REGEX)
logging.info('Got third sleep period, wakeup from {}, slept for {}'.format(match.group(1), match.group(3)))