diff --git a/components/esp_driver_uart/test_apps/.build-test-rules.yml b/components/esp_driver_uart/test_apps/.build-test-rules.yml index eb55777a87..1e0bdf7afb 100644 --- a/components/esp_driver_uart/test_apps/.build-test-rules.yml +++ b/components/esp_driver_uart/test_apps/.build-test-rules.yml @@ -3,9 +3,6 @@ components/esp_driver_uart/test_apps/rs485: disable: - if: SOC_UART_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32h21"] - temporary: true - reason: not support yet # TODO: [esp32h21] IDF-11618 disable_test: - if: IDF_TARGET != "esp32" temporary: true @@ -17,9 +14,6 @@ components/esp_driver_uart/test_apps/rs485: components/esp_driver_uart/test_apps/uart: disable: - if: SOC_UART_SUPPORTED != 1 - - if: IDF_TARGET in ["esp32h21"] - temporary: true - reason: not support yet # TODO: [esp32h21] IDF-11618 depends_components: - esp_driver_uart - esp_driver_gpio diff --git a/components/esp_driver_uart/test_apps/rs485/README.md b/components/esp_driver_uart/test_apps/rs485/README.md index 7b96141437..15bfc62bf3 100644 --- a/components/esp_driver_uart/test_apps/rs485/README.md +++ b/components/esp_driver_uart/test_apps/rs485/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | diff --git a/components/esp_driver_uart/test_apps/uart/README.md b/components/esp_driver_uart/test_apps/uart/README.md index 7b96141437..15bfc62bf3 100644 --- a/components/esp_driver_uart/test_apps/uart/README.md +++ b/components/esp_driver_uart/test_apps/uart/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | diff --git a/components/esp_rom/esp32h21/include/esp32h21/rom/uart.h b/components/esp_rom/esp32h21/include/esp32h21/rom/uart.h index 0d166cf872..7b2f5f8976 100644 --- a/components/esp_rom/esp32h21/include/esp32h21/rom/uart.h +++ b/components/esp_rom/esp32h21/include/esp32h21/rom/uart.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,8 +16,6 @@ extern "C" { #endif -//TODO: [ESP32H21] IDF-11618 - /** \defgroup uart_apis, uart configuration and communication related apis * @brief uart apis */ @@ -26,34 +24,38 @@ extern "C" { * @{ */ +/*It is found that when the buf is only 0x400, and the baud rate is set to 921600, the download is likely to fail */ +#define RX_BUFF_SIZE 0x800 +#define TX_BUFF_SIZE 100 + //uart int enable register ctrl bits -#define UART_RCV_INTEN BIT0 -#define UART_TRX_INTEN BIT1 -#define UART_LINE_STATUS_INTEN BIT2 +#define UART_RCV_INTEN BIT0 +#define UART_TRX_INTEN BIT1 +#define UART_LINE_STATUS_INTEN BIT2 //uart int identification ctrl bits -#define UART_INT_FLAG_MASK 0x0E +#define UART_INT_FLAG_MASK 0x0E //uart fifo ctrl bits -#define UART_CLR_RCV_FIFO BIT1 -#define UART_CLR_TRX_FIFO BIT2 -#define UART_RCVFIFO_TRG_LVL_BITS BIT6 +#define UART_CLR_RCV_FIFO BIT1 +#define UART_CLR_TRX_FIFO BIT2 +#define UART_RCVFIFO_TRG_LVL_BITS BIT6 //uart line control bits -#define UART_DIV_LATCH_ACCESS_BIT BIT7 +#define UART_DIV_LATCH_ACCESS_BIT BIT7 //uart line status bits -#define UART_RCV_DATA_RDY_FLAG BIT0 -#define UART_RCV_OVER_FLOW_FLAG BIT1 -#define UART_RCV_PARITY_ERR_FLAG BIT2 -#define UART_RCV_FRAME_ERR_FLAG BIT3 -#define UART_BRK_INT_FLAG BIT4 -#define UART_TRX_FIFO_EMPTY_FLAG BIT5 -#define UART_TRX_ALL_EMPTY_FLAG BIT6 // include fifo and shift reg -#define UART_RCV_ERR_FLAG BIT7 +#define UART_RCV_DATA_RDY_FLAG BIT0 +#define UART_RCV_OVER_FLOW_FLAG BIT1 +#define UART_RCV_PARITY_ERR_FLAG BIT2 +#define UART_RCV_FRAME_ERR_FLAG BIT3 +#define UART_BRK_INT_FLAG BIT4 +#define UART_TRX_FIFO_EMPTY_FLAG BIT5 +#define UART_TRX_ALL_EMPTY_FLAG BIT6 // include fifo and shift reg +#define UART_RCV_ERR_FLAG BIT7 //send and receive message frame head -#define FRAME_FLAG 0x7E +#define FRAME_FLAG 0x7E typedef enum { UART_LINE_STATUS_INT_FLAG = 0x06, @@ -86,7 +88,6 @@ typedef enum { NONE_BITS = 0, ODD_BITS = 2, EVEN_BITS = 3 - } UartParityMode; typedef enum { @@ -139,7 +140,7 @@ typedef enum { } RcvMsgState; typedef struct { - UartBautRate baut_rate; + UartBautRate baud_rate; UartBitsNum4Char data_bits; UartExistParity exist_parity; UartParityMode parity; // chip size in byte @@ -168,11 +169,9 @@ void uartAttach(void *rxBuffer); * * @param uint8_t uart_no : 0 for UART0, else for UART1. * - * @param uint32_t clock : clock used by uart module, to adjust baudrate. - * * @return None */ -void Uart_Init(uint8_t uart_no, uint32_t clock); +void Uart_Init(uint8_t uart_no); /** * @brief Modify uart baudrate. @@ -186,6 +185,19 @@ void Uart_Init(uint8_t uart_no, uint32_t clock); */ void uart_div_modify(uint8_t uart_no, uint32_t DivLatchValue); +/** + * @brief Init uart0 or uart1 for UART download booting mode. + * Please do not call this function in SDK. + * + * @param uint8_t uart_no : 0 for UART0, 1 for UART1. + * + * @param uint8_t is_sync : 0, only one UART module, easy to detect, wait until detected; + * 1, two UART modules, hard to detect, detect and return. + * + * @return None + */ +int uart_baudrate_detect(uint8_t uart_no, uint8_t is_sync); + /** * @brief Switch printf channel of uart_tx_one_char. * Please do not call this function when printf. @@ -196,6 +208,16 @@ void uart_div_modify(uint8_t uart_no, uint32_t DivLatchValue); */ void uart_tx_switch(uint8_t uart_no); +/** + * @brief Switch message exchange channel for UART download booting. + * Please do not call this function in SDK. + * + * @param uint8_t uart_no : 0 for UART0, 1 for UART1. + * + * @return None + */ +void uart_buff_switch(uint8_t uart_no); + /** * @brief Output a char to printf channel, wait until fifo not full. * @@ -203,7 +225,7 @@ void uart_tx_switch(uint8_t uart_no); * * @return OK. */ -ETS_STATUS uart_tx_one_char(uint8_t TxChar); +ETS_STATUS uart_tx_one_char(uint8_t txchar); /** * @brief Output a char to message exchange channel, wait until fifo not full. @@ -213,7 +235,17 @@ ETS_STATUS uart_tx_one_char(uint8_t TxChar); * * @return OK. */ -ETS_STATUS uart_tx_one_char2(uint8_t TxChar); +ETS_STATUS uart_tx_one_char2(uint8_t txchar); + +/** + * @brief Output a char to usb-serial channel, wait until fifo not full. + * Please do not call this function in SDK. + * + * @param None + * + * @return OK. + */ +ETS_STATUS uart_tx_one_char3(uint8_t txchar); /** * @brief Wait until uart tx full empty. @@ -288,7 +320,7 @@ void uart_rx_intr_handler(void *para); * @return OK for successful. * FAIL for failed. */ -ETS_STATUS uart_rx_readbuff( RcvMsgBuff *pRxBuff, uint8_t *pRxByte); +ETS_STATUS uart_rx_readbuff(RcvMsgBuff *pRxBuff, uint8_t *pRxByte); /** * @brief Get all chars from receive buffer. @@ -338,6 +370,60 @@ void send_packet(uint8_t *p, int len); */ int recv_packet(uint8_t *p, int len, uint8_t is_sync); +/** + * @brief Send an packet to download tool, with SLIP escaping. + * Please do not call this function in SDK. + * + * @param uint8_t *pData : the pointer to input string. + * + * @param uint16_t DataLen : the string length. + * + * @return OK for successful. + * FAIL for failed. + */ +ETS_STATUS SendMsg(uint8_t *pData, uint16_t DataLen); + +/** + * @brief Receive an packet from download tool, with SLIP escaping. + * Please do not call this function in SDK. + * + * @param uint8_t *pData : the pointer to input string. + * + * @param uint16_t MaxDataLen : If string length > MaxDataLen, the string will be truncated. + * + * @param uint8_t is_sync : 0, only one UART module; + * 1, two UART modules. + * + * @return OK for successful. + * FAIL for failed. + */ +ETS_STATUS RcvMsg(uint8_t *pData, uint16_t MaxDataLen, uint8_t is_sync); + +/** + * @brief Check if this UART is in download connection. + * Please do not call this function in SDK. + * + * @param uint8_t uart_no : 0 for UART0, 1 for UART1. + * + * @return ETS_NO_BOOT = 0 for no. + * SEL_UART_BOOT = BIT(1) for yes. + */ +uint8_t UartConnCheck(uint8_t uart_no); + +/** + * @brief Initialize the USB ACM UART + * Needs to be fed a buffer of at least 128 bytes, plus any rx buffer you may want to have. + * + * @param cdc_acm_work_mem Pointer to work mem for CDC-ACM code + * @param cdc_acm_work_mem_len Length of work mem + */ +void Uart_Init_USB(void *cdc_acm_work_mem, int cdc_acm_work_mem_len); + +/** + * @brief Install handler to reset the chip when a RTS change has been detected on the CDC-ACM 'UART'. + */ +void usb_serial_otg_enable_reset_on_rts(void); + extern UartDevice UartDev; /** diff --git a/components/hal/esp32h21/include/hal/uart_ll.h b/components/hal/esp32h21/include/hal/uart_ll.h index 3b5e926454..ff638d4368 100644 --- a/components/hal/esp32h21/include/hal/uart_ll.h +++ b/components/hal/esp32h21/include/hal/uart_ll.h @@ -20,8 +20,6 @@ #include "soc/pcr_reg.h" #include "esp_attr.h" -//TODO: [ESP32H21] IDF-11618, inherit from h2 - #ifdef __cplusplus extern "C" { #endif @@ -59,9 +57,6 @@ extern "C" { #define UART_LL_PCR_REG_GET(hw, reg_suffix, field_suffix) \ (((hw) == &UART0) ? PCR.uart0_##reg_suffix.uart0_##field_suffix : PCR.uart1_##reg_suffix.uart1_##field_suffix) -// UART sleep retention module -#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \ - (uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : -1) #define UART_LL_WAKEUP_EDGE_THRED_MAX(hw) UART_ACTIVE_THRESHOLD_V #define UART_LL_WAKEUP_FIFO_THRED_MAX(hw) UART_RX_WAKE_UP_THRHD_V @@ -99,14 +94,14 @@ typedef enum { */ FORCE_INLINE_ATTR bool uart_ll_is_enabled(uint32_t uart_num) { - uint32_t uart_clk_config_reg = ((uart_num == 0) ? PCR_UART0_CONF_REG : - (uart_num == 1) ? PCR_UART1_CONF_REG : 0); - uint32_t uart_rst_bit = ((uart_num == 0) ? PCR_UART0_RST_EN : - (uart_num == 1) ? PCR_UART1_RST_EN : 0); - uint32_t uart_en_bit = ((uart_num == 0) ? PCR_UART0_CLK_EN : - (uart_num == 1) ? PCR_UART1_CLK_EN : 0); - return REG_GET_BIT(uart_clk_config_reg, uart_rst_bit) == 0 && - REG_GET_BIT(uart_clk_config_reg, uart_en_bit) != 0; + switch (uart_num) { + case 0: + return PCR.uart0_conf.uart0_clk_en && !PCR.uart0_conf.uart0_rst_en; + case 1: + return PCR.uart1_conf.uart1_clk_en && !PCR.uart1_conf.uart1_rst_en; + default: + return false; + } } /** @@ -253,7 +248,9 @@ FORCE_INLINE_ATTR void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint3 const uint32_t max_div = BIT(12) - 1; // UART divider integer part only has 12 bits uint32_t sclk_div = DIV_UP(sclk_freq, (uint64_t)max_div * baud); - if (sclk_div == 0) abort(); + if (sclk_div == 0) { + abort(); + } uint32_t clk_div = ((sclk_freq) << 4) / (baud * sclk_div); // The baud rate configuration register is divided into @@ -429,7 +426,7 @@ FORCE_INLINE_ATTR void uart_ll_txfifo_rst(uart_dev_t *hw) */ FORCE_INLINE_ATTR uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) { - return hw->status.rxfifo_cnt; + return HAL_FORCE_READ_U32_REG_FIELD(hw->status, rxfifo_cnt); } /** @@ -441,7 +438,7 @@ FORCE_INLINE_ATTR uint32_t uart_ll_get_rxfifo_len(uart_dev_t *hw) */ FORCE_INLINE_ATTR uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) { - return UART_LL_FIFO_DEF_LEN - hw->status.txfifo_cnt; + return UART_LL_FIFO_DEF_LEN - HAL_FORCE_READ_U32_REG_FIELD(hw->status, txfifo_cnt); } /** @@ -516,7 +513,7 @@ FORCE_INLINE_ATTR void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_ */ FORCE_INLINE_ATTR void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) { - hw->conf1.rxfifo_full_thrhd = full_thrhd; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->conf1, rxfifo_full_thrhd, full_thrhd); } /** @@ -530,7 +527,7 @@ FORCE_INLINE_ATTR void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full */ FORCE_INLINE_ATTR void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) { - hw->conf1.txfifo_empty_thrhd = empty_thrhd; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->conf1, txfifo_empty_thrhd, empty_thrhd); } /** @@ -594,7 +591,7 @@ FORCE_INLINE_ATTR void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcont { //only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set. if (flow_ctrl & UART_HW_FLOWCTRL_RTS) { - hw->hwfc_conf_sync.rx_flow_thrhd = rx_thrs; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->hwfc_conf_sync, rx_flow_thrhd, rx_thrs); hw->hwfc_conf_sync.rx_flow_en = 1; } else { hw->hwfc_conf_sync.rx_flow_en = 0; @@ -640,10 +637,10 @@ FORCE_INLINE_ATTR void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl if (sw_flow_ctrl_en) { hw->swfc_conf0_sync.xonoff_del = 1; hw->swfc_conf0_sync.sw_flow_con_en = 1; - hw->swfc_conf1.xon_threshold = flow_ctrl->xon_thrd; - hw->swfc_conf1.xoff_threshold = flow_ctrl->xoff_thrd; - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xon_char, flow_ctrl->xon_char); - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xoff_char, flow_ctrl->xoff_char); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf1, xon_threshold, flow_ctrl->xon_thrd); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf1, xoff_threshold, flow_ctrl->xoff_thrd); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xon_character, flow_ctrl->xon_char); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xoff_character, flow_ctrl->xoff_char); } else { hw->swfc_conf0_sync.sw_flow_con_en = 0; hw->swfc_conf0_sync.xonoff_del = 0; @@ -1021,7 +1018,7 @@ FORCE_INLINE_ATTR void uart_ll_get_data_bit_num(uart_dev_t *hw, uart_word_length */ FORCE_INLINE_ATTR bool uart_ll_is_tx_idle(uart_dev_t *hw) { - return ((hw->status.txfifo_cnt == 0) && (hw->fsm_status.st_utx_out == 0)); + return ((HAL_FORCE_READ_U32_REG_FIELD(hw->status, txfifo_cnt) == 0) && (hw->fsm_status.st_utx_out == 0)); } /** @@ -1066,7 +1063,7 @@ FORCE_INLINE_ATTR void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) { hw->swfc_conf0_sync.force_xon = 1; uart_ll_update(hw); - if(!always_on) { + if (!always_on) { hw->swfc_conf0_sync.force_xon = 0; uart_ll_update(hw); } @@ -1112,7 +1109,7 @@ FORCE_INLINE_ATTR void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) { uint16_t tout_val = tout_thrd; - if(tout_thrd > 0) { + if (tout_thrd > 0) { hw->tout_conf_sync.rx_tout_thrhd = tout_val; hw->tout_conf_sync.rx_tout_en = 1; } else { @@ -1131,7 +1128,7 @@ FORCE_INLINE_ATTR void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) FORCE_INLINE_ATTR uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw) { uint16_t tout_thrd = 0; - if(hw->tout_conf_sync.rx_tout_en > 0) { + if (hw->tout_conf_sync.rx_tout_en > 0) { tout_thrd = hw->tout_conf_sync.rx_tout_thrhd; } return tout_thrd; diff --git a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in index 77c9ef49f3..8552d04128 100644 --- a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in @@ -627,6 +627,10 @@ config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND bool default y +config SOC_UART_SUPPORT_SLEEP_RETENTION + bool + default y + config SOC_UART_WAKEUP_CHARS_SEQ_MAX_LEN int default 5 diff --git a/components/soc/esp32h21/include/soc/clk_tree_defs.h b/components/soc/esp32h21/include/soc/clk_tree_defs.h index 058994ba54..ec93a1b968 100644 --- a/components/soc/esp32h21/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h21/include/soc/clk_tree_defs.h @@ -196,7 +196,11 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of UART */ +#if SOC_CLK_TREE_SUPPORTED #define SOC_UART_CLKS {SOC_MOD_CLK_PLL_F48M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST} +#else +#define SOC_UART_CLKS {SOC_MOD_CLK_XTAL} +#endif /** * @brief Type of UART clock source, reserved for the legacy UART driver @@ -205,7 +209,11 @@ typedef enum { UART_SCLK_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< UART source clock is PLL_F48M */ UART_SCLK_RTC = SOC_MOD_CLK_RC_FAST, /*!< UART source clock is RC_FAST */ UART_SCLK_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */ - UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< UART source clock default choice is PLL_F48M */ +#if SOC_CLK_TREE_SUPPORTED + UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_F48M as the default choice */ +#else + UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default choice if no clk_tree */ +#endif } soc_periph_uart_clk_src_legacy_t; /////////////////////////////////////////////////SPI//////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32h21/include/soc/soc_caps.h b/components/soc/esp32h21/include/soc/soc_caps.h index 1b3c480f6a..8fa9630b31 100644 --- a/components/soc/esp32h21/include/soc/soc_caps.h +++ b/components/soc/esp32h21/include/soc/soc_caps.h @@ -20,7 +20,7 @@ // #define SOC_ADC_SUPPORTED 1 //TODO: [ESP32H21] IDF-11589, IDF-11592 // #define SOC_ANA_CMPR_SUPPORTED 1 // #define SOC_DEDICATED_GPIO_SUPPORTED 1 //TODO: [ESP32H21] IDF-11621 -#define SOC_UART_SUPPORTED 1 //TODO: [ESP32H21] IDF-11618 +#define SOC_UART_SUPPORTED 1 // #define SOC_GDMA_SUPPORTED 1 //TODO: [ESP32H21] IDF-11603 // #define SOC_AHB_GDMA_SUPPORTED 1 //TODO: [ESP32H21] IDF-11603 #define SOC_GPTIMER_SUPPORTED 1 @@ -499,7 +499,7 @@ // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) -// #define SOC_UART_SUPPORT_SLEEP_RETENTION (1) /*!< Support back up registers before sleep */ +#define SOC_UART_SUPPORT_SLEEP_RETENTION (1) /*!< Support back up registers before sleep */ #define SOC_UART_WAKEUP_CHARS_SEQ_MAX_LEN 5 #define SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE (1) diff --git a/components/soc/esp32h21/include/soc/uart_channel.h b/components/soc/esp32h21/include/soc/uart_channel.h index 64b092e06e..b207b6e11e 100644 --- a/components/soc/esp32h21/include/soc/uart_channel.h +++ b/components/soc/esp32h21/include/soc/uart_channel.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,10 +9,10 @@ #pragma once //UART channels -#define UART_GPIO24_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 24 -#define UART_GPIO23_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 23 +#define UART_GPIO16_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 16 +#define UART_GPIO15_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 15 -#define UART_TXD_GPIO24_DIRECT_CHANNEL UART_GPIO24_DIRECT_CHANNEL -#define UART_RXD_GPIO23_DIRECT_CHANNEL UART_GPIO23_DIRECT_CHANNEL +#define UART_TXD_GPIO16_DIRECT_CHANNEL UART_GPIO16_DIRECT_CHANNEL +#define UART_RXD_GPIO15_DIRECT_CHANNEL UART_GPIO15_DIRECT_CHANNEL diff --git a/components/soc/esp32h21/register/soc/uart_struct.h b/components/soc/esp32h21/register/soc/uart_struct.h index 8580b21145..5703d8d266 100644 --- a/components/soc/esp32h21/register/soc/uart_struct.h +++ b/components/soc/esp32h21/register/soc/uart_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -16,11 +16,10 @@ extern "C" { */ typedef union { struct { - /** rxfifo_rd_byte : RO; bitpos: [7:0]; default: 0; + /** rxfifo_rd_byte : RO; bitpos: [31:0]; default: 0; * UART $n accesses FIFO via this register. */ - uint32_t rxfifo_rd_byte:8; - uint32_t reserved_8:24; + uint32_t rxfifo_rd_byte:32; }; uint32_t val; } uart_fifo_reg_t; @@ -738,14 +737,14 @@ typedef union { */ typedef union { struct { - /** xon_char : R/W; bitpos: [7:0]; default: 17; + /** xon_character : R/W; bitpos: [7:0]; default: 17; * This register stores the Xon flow control char. */ - uint32_t xon_char:8; - /** xoff_char : R/W; bitpos: [15:8]; default: 19; + uint32_t xon_character:8; + /** xoff_character : R/W; bitpos: [15:8]; default: 19; * This register stores the Xoff flow control char. */ - uint32_t xoff_char:8; + uint32_t xoff_character:8; /** xon_xoff_still_send : R/W; bitpos: [16]; default: 0; * In software flow control mode, UART Tx is disabled once UART Rx receives XOFF. In * this status, UART Tx can not transmit XOFF even the received data number is larger diff --git a/components/soc/esp32h21/uart_periph.c b/components/soc/esp32h21/uart_periph.c index ad395af7e0..09022ec856 100644 --- a/components/soc/esp32h21/uart_periph.c +++ b/components/soc/esp32h21/uart_periph.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,8 +7,6 @@ #include "soc/uart_periph.h" #include "soc/uart_reg.h" -//TODO: [ESP32H21] IDF-11618 - /* Bunch of constants for every UART peripheral: GPIO signals, irqs, hw addr of registers etc */ @@ -79,3 +77,54 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = { .irq = ETS_UART1_INTR_SOURCE, }, }; + +/** + * UART registers to be saved during sleep retention + * + * Reset TXFIFO and RXFIFO + * UART registers require set the reg_update bit to make the configuration take effect + * + * UART_INT_ENA_REG, UART_CLKDIV_SYNC_REG, UART_RX_FILT_REG, UART_CONF0_SYNC_REG, UART_CONF1_REG, + * UART_HWFC_CONF_SYNC_REG, UART_SLEEP_CONF0_REG, UART_SLEEP_CONF1_REG, UART_SLEEP_CONF2_REG, + * UART_SWFC_CONF0_SYNC_REG, UART_SWFC_CONF1_REG, UART_TXBRK_CONF_SYNC_REG, UART_IDLE_CONF_SYNC_REG, + * UART_RS485_CONF_SYNC_REG, UART_AT_CMD_PRECNT_SYNC_REG, UART_AT_CMD_POSTCNT_SYNC_REG, UART_AT_CMD_GAPTOUT_SYNC_REG, + * UART_AT_CMD_CHAR_SYNC_REG, UART_MEM_CONF_REG, UART_TOUT_CONF_SYNC_REG, UART_CLK_CONF_REG, UART_ID_REG + */ +#define UART_RETENTION_ADDR_MAP_REGS_CNT 22 +#define UART_RETENTION_REGS_BASE(i) UART_INT_ENA_REG(i) +static const uint32_t uart_regs_map[4] = {0x807fff6d, 0x10, 0x0, 0x0}; +#define UART_SLEEP_RETENTION_ENTRIES(uart_num) { \ + [0] = {.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_UART_LINK(0x00), \ + UART_RETENTION_REGS_BASE(uart_num), UART_RETENTION_REGS_BASE(uart_num), \ + UART_RETENTION_ADDR_MAP_REGS_CNT, 0, 0, \ + uart_regs_map[0], uart_regs_map[1], \ + uart_regs_map[2], uart_regs_map[3] \ + ), \ + .owner = ENTRY(0) | ENTRY(2) }, \ + [1] = {.config = REGDMA_LINK_WRITE_INIT(REGDMA_UART_LINK(0x01), \ + UART_REG_UPDATE_REG(uart_num), UART_REG_UPDATE, \ + UART_REG_UPDATE_M, 1, 0 \ + ), \ + .owner = ENTRY(0) | ENTRY(2) }, \ + [2] = {.config = REGDMA_LINK_WAIT_INIT(REGDMA_UART_LINK(0x02), \ + UART_REG_UPDATE_REG(uart_num), 0x0, \ + UART_REG_UPDATE_M, 1, 0 \ + ), \ + .owner = ENTRY(0) | ENTRY(2) }, \ +} + +static const regdma_entries_config_t uart0_regdma_entries[] = UART_SLEEP_RETENTION_ENTRIES(0); +static const regdma_entries_config_t uart1_regdma_entries[] = UART_SLEEP_RETENTION_ENTRIES(1); + +const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM] = { + [0] = { + .module = SLEEP_RETENTION_MODULE_UART0, + .regdma_entry_array = uart0_regdma_entries, + .array_size = ARRAY_SIZE(uart0_regdma_entries), + }, + [1] = { + .module = SLEEP_RETENTION_MODULE_UART1, + .regdma_entry_array = uart1_regdma_entries, + .array_size = ARRAY_SIZE(uart1_regdma_entries), + }, +}; diff --git a/docs/docs_not_updated/esp32h21.txt b/docs/docs_not_updated/esp32h21.txt index 426ece81ab..0da5cb4a43 100644 --- a/docs/docs_not_updated/esp32h21.txt +++ b/docs/docs_not_updated/esp32h21.txt @@ -192,7 +192,6 @@ api-reference/peripherals/ana_cmpr.rst api-reference/peripherals/i2c_slave_v1.rst api-reference/peripherals/adc_continuous.rst api-reference/peripherals/hmac.rst -api-reference/peripherals/uart.rst api-reference/peripherals/sdspi_host.rst api-reference/peripherals/spi_slave_hd.rst api-reference/peripherals/vad.rst