kopia lustrzana https://github.com/espressif/esp-idf
fix(uart): Fix mismatch wakeup rising edges required with the threshold configured
Closes https://github.com/espressif/esp-idf/issues/12586release/v5.1
rodzic
2fd087b246
commit
a664c71fd7
|
@ -1719,7 +1719,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_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((uart_num < UART_NUM_MAX), ESP_ERR_INVALID_ARG, UART_TAG, "uart_num error");
|
||||||
ESP_RETURN_ON_FALSE((wakeup_threshold <= UART_ACTIVE_THRESHOLD_V && wakeup_threshold > UART_MIN_WAKEUP_THRESH), ESP_ERR_INVALID_ARG, UART_TAG,
|
ESP_RETURN_ON_FALSE((wakeup_threshold <= UART_ACTIVE_THRESHOLD_V && wakeup_threshold >= UART_MIN_WAKEUP_THRESH), ESP_ERR_INVALID_ARG, UART_TAG,
|
||||||
"wakeup_threshold out of bounds");
|
"wakeup_threshold out of bounds");
|
||||||
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
||||||
uart_hal_set_wakeup_thrd(&(uart_context[uart_num].hal), wakeup_threshold);
|
uart_hal_set_wakeup_thrd(&(uart_context[uart_num].hal), wakeup_threshold);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
@ -28,7 +28,7 @@ extern "C" {
|
||||||
// The timeout calibration factor when using ref_tick
|
// The timeout calibration factor when using ref_tick
|
||||||
#define UART_LL_TOUT_REF_FACTOR_DEFAULT (8)
|
#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_LL_INTR_MASK (0x7ffff) //All interrupt mask
|
||||||
|
|
||||||
// Define UART interrupts
|
// Define UART interrupts
|
||||||
|
@ -597,7 +597,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)
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -739,7 +741,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)
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
||||||
// Get UART hardware instance with giving uart num
|
// Get UART hardware instance with giving uart num
|
||||||
#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1))
|
#define UART_LL_GET_HW(num) (((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_INTR_MASK (0x7ffff) //All interrupt mask
|
||||||
|
|
||||||
#define UART_LL_FSM_IDLE (0x0)
|
#define UART_LL_FSM_IDLE (0x0)
|
||||||
|
@ -616,6 +616,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)
|
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;
|
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ extern "C" {
|
||||||
// Get UART hardware instance with giving uart num
|
// Get UART hardware instance with giving uart num
|
||||||
#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1))
|
#define UART_LL_GET_HW(num) (((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_INTR_MASK (0x7ffff) //All interrupt mask
|
||||||
|
|
||||||
#define UART_LL_FSM_IDLE (0x0)
|
#define UART_LL_FSM_IDLE (0x0)
|
||||||
|
@ -616,6 +616,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)
|
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;
|
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ extern "C" {
|
||||||
// Get UART hardware instance with giving uart num
|
// Get UART hardware instance with giving uart num
|
||||||
#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1))
|
#define UART_LL_GET_HW(num) (((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_INTR_MASK (0x7ffff) //All interrupt mask
|
||||||
|
|
||||||
#define UART_LL_FSM_IDLE (0x0)
|
#define UART_LL_FSM_IDLE (0x0)
|
||||||
|
@ -663,6 +663,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)
|
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;
|
hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
||||||
// Get UART hardware instance with giving uart num
|
// Get UART hardware instance with giving uart num
|
||||||
#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1))
|
#define UART_LL_GET_HW(num) (((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_INTR_MASK (0x7ffff) //All interrupt mask
|
||||||
|
|
||||||
#define UART_LL_FSM_IDLE (0x0)
|
#define UART_LL_FSM_IDLE (0x0)
|
||||||
|
@ -664,6 +664,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)
|
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;
|
hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
||||||
// Get UART hardware instance with giving uart num
|
// Get UART hardware instance with giving uart num
|
||||||
#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (&UART1))
|
#define UART_LL_GET_HW(num) (((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_INTR_MASK (0x7ffff) //All interrupt mask
|
||||||
|
|
||||||
// Define UART interrupts
|
// Define UART interrupts
|
||||||
|
@ -547,6 +547,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)
|
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;
|
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ extern "C" {
|
||||||
// Get UART hardware instance with giving uart num
|
// Get UART hardware instance with giving uart num
|
||||||
#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (((num) == 1) ? (&UART1) : (&UART2)))
|
#define UART_LL_GET_HW(num) (((num) == 0) ? (&UART0) : (((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_INTR_MASK (0x7ffff) //All interrupt mask
|
||||||
|
|
||||||
#define UART_LL_FSM_IDLE (0x0)
|
#define UART_LL_FSM_IDLE (0x0)
|
||||||
|
@ -589,6 +589,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)
|
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;
|
hw->sleep_conf.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,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.
|
: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
|
.. only:: esp32c6 or esp32h2
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
|
@ -191,6 +191,8 @@ UART 唤醒(仅适用于 Light-sleep 模式)
|
||||||
|
|
||||||
可调用 :cpp:func:`esp_sleep_enable_uart_wakeup` 函数来启用此唤醒源。
|
可调用 :cpp:func:`esp_sleep_enable_uart_wakeup` 函数来启用此唤醒源。
|
||||||
|
|
||||||
|
使用 UART 唤醒之后,在芯片 Active 模式下需要让 UART 接受一些数据用来清零内部的唤醒指示信号。不然的话,下一次 UART 唤醒的触发将只需要比配置的阈值少两个上升沿的数量。
|
||||||
|
|
||||||
.. only:: esp32c6 or esp32h2
|
.. only:: esp32c6 or esp32h2
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
|
@ -11,7 +11,7 @@ The example enables the following wakeup sources:
|
||||||
|
|
||||||
- Timer: wake up the chip in 2 seconds
|
- 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)
|
- 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.
|
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.
|
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 #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 #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
|
### Wake-up by Touch Pad
|
||||||
|
|
||||||
For this example, pressing any registered touch buttons can wake up the chip.
|
For this example, pressing any registered touch buttons can wake up the chip.
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -53,8 +52,8 @@ def test_light_sleep(dut: Dut) -> None:
|
||||||
dut.expect_exact(ENTERING_SLEEP_STR)
|
dut.expect_exact(ENTERING_SLEEP_STR)
|
||||||
logging.info('Went to sleep again')
|
logging.info('Went to sleep again')
|
||||||
|
|
||||||
# Write 'U' to uart, 'U' in ascii is 0x55 which contains 8 edges in total
|
# Write 'a' to uart, 'a' in ascii is 0x61 which contains 3 rising edges in total (including the stop bit)
|
||||||
dut.write('U')
|
dut.write('a')
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
match = dut.expect(EXIT_SLEEP_UART_REGEX)
|
match = dut.expect(EXIT_SLEEP_UART_REGEX)
|
||||||
logging.info('Got third sleep period, wakeup from {}, slept for {}'.format(match.group(1), match.group(3)))
|
logging.info('Got third sleep period, wakeup from {}, slept for {}'.format(match.group(1), match.group(3)))
|
||||||
|
|
Ładowanie…
Reference in New Issue