From 06442fd3190c8198dc653bc58d1e9830132ae94b Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 7 Mar 2024 16:59:20 +0800 Subject: [PATCH] fix(uart): Fix mismatch wakeup rising edges required with the threshold configured Closes https://github.com/espressif/esp-idf/issues/12586 --- components/driver/uart.c | 2 +- components/hal/esp32/include/hal/uart_ll.h | 26 ++++++++------------ components/hal/esp32c3/include/hal/uart_ll.h | 3 ++- components/hal/esp32h2/include/hal/uart_ll.h | 3 ++- components/hal/esp32s2/include/hal/uart_ll.h | 3 ++- components/hal/esp32s3/include/hal/uart_ll.h | 3 ++- docs/en/api-reference/system/sleep_modes.rst | 1 + 7 files changed, 20 insertions(+), 21 deletions(-) diff --git a/components/driver/uart.c b/components/driver/uart.c index d57458f552..a4cc13b6d7 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -1771,7 +1771,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_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"); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); uart_hal_set_wakeup_thrd(&(uart_context[uart_num].hal), wakeup_threshold); diff --git a/components/hal/esp32/include/hal/uart_ll.h b/components/hal/esp32/include/hal/uart_ll.h index 646e11d46b..57bab2169b 100644 --- a/components/hal/esp32/include/hal/uart_ll.h +++ b/components/hal/esp32/include/hal/uart_ll.h @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ // The LL layer for UART register operations. // Note that most of the register operations in this layer are non-atomic operations. @@ -36,7 +28,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 @@ -617,7 +609,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); } /** @@ -759,7 +753,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); } /** diff --git a/components/hal/esp32c3/include/hal/uart_ll.h b/components/hal/esp32c3/include/hal/uart_ll.h index 6206057f1a..d46a0498b2 100644 --- a/components/hal/esp32c3/include/hal/uart_ll.h +++ b/components/hal/esp32c3/include/hal/uart_ll.h @@ -25,7 +25,7 @@ extern "C" { // Get UART hardware instance with giving uart num #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_FSM_IDLE (0x0) @@ -610,6 +610,7 @@ static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) */ static inline 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; } diff --git a/components/hal/esp32h2/include/hal/uart_ll.h b/components/hal/esp32h2/include/hal/uart_ll.h index 319d1faa52..4d40129330 100644 --- a/components/hal/esp32h2/include/hal/uart_ll.h +++ b/components/hal/esp32h2/include/hal/uart_ll.h @@ -33,7 +33,7 @@ extern "C" { // Get UART hardware instance with giving uart num #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_FSM_IDLE (0x0) @@ -618,6 +618,7 @@ static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) */ static inline 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; } diff --git a/components/hal/esp32s2/include/hal/uart_ll.h b/components/hal/esp32s2/include/hal/uart_ll.h index d1dd4afb26..21a46b5cad 100644 --- a/components/hal/esp32s2/include/hal/uart_ll.h +++ b/components/hal/esp32s2/include/hal/uart_ll.h @@ -25,7 +25,7 @@ extern "C" { // Get UART hardware instance with giving uart num #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 interrupts @@ -559,6 +559,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; } diff --git a/components/hal/esp32s3/include/hal/uart_ll.h b/components/hal/esp32s3/include/hal/uart_ll.h index efb32e14f4..64477f1696 100644 --- a/components/hal/esp32s3/include/hal/uart_ll.h +++ b/components/hal/esp32s3/include/hal/uart_ll.h @@ -26,7 +26,7 @@ extern "C" { // Get UART hardware instance with giving uart num #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_FSM_IDLE (0x0) @@ -609,6 +609,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; } diff --git a/docs/en/api-reference/system/sleep_modes.rst b/docs/en/api-reference/system/sleep_modes.rst index d1e6175bdb..302736a8e5 100644 --- a/docs/en/api-reference/system/sleep_modes.rst +++ b/docs/en/api-reference/system/sleep_modes.rst @@ -170,6 +170,7 @@ When {IDF_TARGET_NAME} receives UART input from external devices, it is often re :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. Power-down of RTC peripherals and memories ------------------------------------------