From e90d76e5b70a3f6fba5db9f2fd702a38e2c01ffb Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 9 Nov 2022 19:17:35 +0800 Subject: [PATCH 1/3] bugfix: fix uart fifo lost data issue --- components/hal/esp32c6/include/hal/uart_ll.h | 4 ++-- components/soc/esp32c6/include/soc/uart_struct.h | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/components/hal/esp32c6/include/hal/uart_ll.h b/components/hal/esp32c6/include/hal/uart_ll.h index 5411edebbf..c98beed511 100644 --- a/components/hal/esp32c6/include/hal/uart_ll.h +++ b/components/hal/esp32c6/include/hal/uart_ll.h @@ -271,7 +271,7 @@ static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw) static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd_len) { for (int i = 0; i < (int)rd_len; i++) { - buf[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->fifo, rxfifo_rd_byte); + buf[i] = hw->fifo.rxfifo_rd_byte; } } @@ -287,7 +287,7 @@ static inline void uart_ll_read_rxfifo(uart_dev_t *hw, uint8_t *buf, uint32_t rd static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint32_t wr_len) { for (int i = 0; i < (int)wr_len; i++) { - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->fifo, rxfifo_rd_byte, buf[i]); + hw->fifo.rxfifo_rd_byte = buf[i]; } } diff --git a/components/soc/esp32c6/include/soc/uart_struct.h b/components/soc/esp32c6/include/soc/uart_struct.h index 487c05b90a..d1deab0044 100644 --- a/components/soc/esp32c6/include/soc/uart_struct.h +++ b/components/soc/esp32c6/include/soc/uart_struct.h @@ -19,8 +19,7 @@ typedef union { /** rxfifo_rd_byte : RO; bitpos: [7: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; From 7778ab6d5c843737417c9277b61b34467d182e0b Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Tue, 15 Nov 2022 11:52:43 +0800 Subject: [PATCH 2/3] uart: support update_reg and PCR clock for all uart devices --- components/hal/esp32c6/include/hal/uart_ll.h | 205 +++++++++--------- .../soc/esp32c6/include/soc/clk_tree_defs.h | 4 + .../soc/esp32c6/include/soc/uart_struct.h | 2 +- 3 files changed, 113 insertions(+), 98 deletions(-) diff --git a/components/hal/esp32c6/include/hal/uart_ll.h b/components/hal/esp32c6/include/hal/uart_ll.h index c98beed511..372d3aeff4 100644 --- a/components/hal/esp32c6/include/hal/uart_ll.h +++ b/components/hal/esp32c6/include/hal/uart_ll.h @@ -14,6 +14,7 @@ #include "hal/uart_types.h" #include "soc/uart_periph.h" #include "soc/uart_struct.h" +#include "soc/pcr_struct.h" #ifdef __cplusplus extern "C" { @@ -30,6 +31,16 @@ extern "C" { #define UART_LL_FSM_IDLE (0x0) #define UART_LL_FSM_TX_WAIT_SEND (0xf) +#define UART_LL_PCR_REG_SET(hw, reg_suffix, field_suffix, val) \ + if ((hw) == &UART0) { \ + PCR.uart0_##reg_suffix.uart0_##field_suffix = (val); \ + } else { \ + PCR.uart1_##reg_suffix.uart1_##field_suffix = (val); \ + } + +#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) + // Define UART interrupts typedef enum { UART_INTR_RXFIFO_FULL = (0x1 << 0), @@ -54,16 +65,11 @@ typedef enum { // UART_INTR_WAKEUP = (0x1 << 19), // TODO: IDF-5338 } uart_intr_t; -static inline void uart_ll_update(int uart_no) // TODO: IDF-5338 should use uart_dev_t *hw +static inline void uart_ll_update(uart_dev_t *hw) { // TODO: set a timeout ?? - while(1) { - int update = GET_PERI_REG_BITS2(UART_REG_UPDATE_REG(uart_no), UART_REG_UPDATE_V, UART_REG_UPDATE_S); - if (!update) { - break; - } - } - SET_PERI_REG_MASK(UART_REG_UPDATE_REG(uart_no), UART_REG_UPDATE_M); + while (hw->reg_update.reg_update); + hw->reg_update.reg_update = 1; } /** @@ -76,7 +82,7 @@ static inline void uart_ll_update(int uart_no) // TODO: IDF-5338 should use uart */ static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) { - hw->clk_conf.rst_core = core_rst_en; + UART_LL_PCR_REG_SET(hw, conf, rst_en, core_rst_en); } /** @@ -88,9 +94,8 @@ static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) */ static inline void uart_ll_sclk_enable(uart_dev_t *hw) { - hw->clk_conf.sclk_en = 1; - hw->clk_conf.rx_sclk_en = 1; - hw->clk_conf.tx_sclk_en = 1; + UART_LL_PCR_REG_SET(hw, conf, clk_en, 1); + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1); } /** @@ -102,9 +107,8 @@ static inline void uart_ll_sclk_enable(uart_dev_t *hw) */ static inline void uart_ll_sclk_disable(uart_dev_t *hw) { - hw->clk_conf.sclk_en = 0; - hw->clk_conf.rx_sclk_en = 0; - hw->clk_conf.tx_sclk_en = 0; + UART_LL_PCR_REG_SET(hw, conf, clk_en, 0); + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0); } /** @@ -121,13 +125,13 @@ static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) switch (source_clk) { default: case UART_SCLK_APB: - hw->clk_conf.sclk_sel = 1; + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 1); break; case UART_SCLK_RTC: - hw->clk_conf.sclk_sel = 2; + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 2); break; case UART_SCLK_XTAL: - hw->clk_conf.sclk_sel = 3; + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 3); break; } } @@ -142,7 +146,7 @@ static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) */ static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk) { - switch (hw->clk_conf.sclk_sel) { + switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) { default: case 1: *source_clk = UART_SCLK_APB; @@ -176,9 +180,9 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t // an integer part and a fractional part. hw->clkdiv_sync.clkdiv_int = clk_div >> 4; hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf; - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clk_conf, sclk_div_num, sclk_div - 1); + UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1); #undef DIV_UP - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -193,7 +197,7 @@ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) { typeof(hw->clkdiv_sync) div_reg; div_reg.val = hw->clkdiv_sync.val; - return ((sclk_freq << 4)) / (((div_reg.clkdiv_int << 4) | div_reg.clkdiv_frag) * (HAL_FORCE_READ_U32_REG_FIELD(hw->clk_conf, sclk_div_num) + 1)); + return ((sclk_freq << 4)) / (((div_reg.clkdiv_int << 4) | div_reg.clkdiv_frag) * (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_div_num) + 1)); } /** @@ -207,6 +211,7 @@ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) { hw->int_ena.val |= mask; + uart_ll_update(hw); } /** @@ -220,6 +225,7 @@ static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) { hw->int_ena.val &= (~mask); + uart_ll_update(hw); } /** @@ -245,6 +251,7 @@ static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) { hw->int_clr.val = mask; + uart_ll_update(hw); } /** @@ -301,9 +308,9 @@ static inline void uart_ll_write_txfifo(uart_dev_t *hw, const uint8_t *buf, uint static inline void uart_ll_rxfifo_rst(uart_dev_t *hw) { hw->conf0_sync.rxfifo_rst = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.rxfifo_rst = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -316,9 +323,9 @@ static inline void uart_ll_rxfifo_rst(uart_dev_t *hw) static inline void uart_ll_txfifo_rst(uart_dev_t *hw) { hw->conf0_sync.txfifo_rst = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.txfifo_rst = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -356,7 +363,7 @@ static inline uint32_t uart_ll_get_txfifo_len(uart_dev_t *hw) static inline void uart_ll_set_stop_bits(uart_dev_t *hw, uart_stop_bits_t stop_bit) { hw->conf0_sync.stop_bit_num = stop_bit; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -386,7 +393,7 @@ static inline void uart_ll_set_parity(uart_dev_t *hw, uart_parity_t parity_mode) hw->conf0_sync.parity = parity_mode & 0x1; } hw->conf0_sync.parity_en = (parity_mode >> 1) & 0x1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -418,6 +425,7 @@ static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) { hw->conf1.rxfifo_full_thrhd = full_thrhd; + uart_ll_update(hw); } /** @@ -432,6 +440,7 @@ static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thr static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) { hw->conf1.txfifo_empty_thrhd = empty_thrhd; + uart_ll_update(hw); } /** @@ -446,7 +455,7 @@ static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_t static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) { hw->idle_conf_sync.rx_idle_thrhd = rx_idle_thr; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -460,7 +469,7 @@ static inline void uart_ll_set_rx_idle_thr(uart_dev_t *hw, uint32_t rx_idle_thr) static inline void uart_ll_set_tx_idle_num(uart_dev_t *hw, uint32_t idle_num) { hw->idle_conf_sync.tx_idle_num = idle_num; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -475,12 +484,12 @@ static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) { if (break_num > 0) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->txbrk_conf_sync, tx_brk_num, break_num); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.txd_brk = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } else { hw->conf0_sync.txd_brk = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } } @@ -498,19 +507,19 @@ static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_ //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; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->hwfc_conf_sync.rx_flow_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } else { hw->hwfc_conf_sync.rx_flow_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } if (flow_ctrl & UART_HW_FLOWCTRL_CTS) { hw->conf0_sync.tx_flow_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } else { hw->conf0_sync.tx_flow_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } } @@ -546,20 +555,20 @@ static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t * { if (sw_flow_ctrl_en) { hw->swfc_conf0_sync.xonoff_del = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->swfc_conf0_sync.sw_flow_con_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); 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); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xoff_char, flow_ctrl->xoff_char); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } else { hw->swfc_conf0_sync.sw_flow_con_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->swfc_conf0_sync.xonoff_del = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } } @@ -579,15 +588,15 @@ static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t * static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, data, cmd_char->cmd_char); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, char_num, cmd_char->char_num); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_postcnt_sync, post_idle_num, cmd_char->post_idle); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_precnt_sync, pre_idle_num, cmd_char->pre_idle); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_gaptout_sync, rx_gap_tout, cmd_char->gap_tout); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -601,7 +610,7 @@ static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_ch static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t data_bit) { hw->conf0_sync.bit_num = data_bit; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -615,7 +624,7 @@ static inline void uart_ll_set_data_bit_num(uart_dev_t *hw, uart_word_length_t d static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) { hw->conf0_sync.sw_rts = level & 0x1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -629,6 +638,7 @@ static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) { hw->conf1.sw_dtr = level & 0x1; + uart_ll_update(hw); } /** @@ -643,6 +653,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) { hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; + uart_ll_update(hw); } /** @@ -655,13 +666,13 @@ static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) static inline void uart_ll_set_mode_normal(uart_dev_t *hw) { hw->rs485_conf_sync.rs485_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.rs485tx_rx_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.rs485rxby_tx_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.irda_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -675,19 +686,19 @@ static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) { // Application software control, remove echo hw->rs485_conf_sync.rs485rxby_tx_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.irda_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.sw_rts = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.irda_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.dl0_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.dl1_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.rs485_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -701,22 +712,22 @@ static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) { // Enable receiver, sw_rts = 1 generates low level on RTS pin hw->conf0_sync.sw_rts = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); // Half duplex mode hw->rs485_conf_sync.rs485tx_rx_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); // Setting this bit will allow data to be transmitted while receiving data(full-duplex mode). // But note that this full-duplex mode has no conflict detection function hw->rs485_conf_sync.rs485rxby_tx_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.irda_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.dl0_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.dl1_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.rs485_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -729,21 +740,21 @@ static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw) { hw->conf0_sync.irda_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); // Enable full-duplex mode hw->rs485_conf_sync.rs485tx_rx_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); // Transmitter should send data when the receiver is busy, hw->rs485_conf_sync.rs485rxby_tx_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.dl0_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.dl1_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.sw_rts = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.rs485_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -756,15 +767,15 @@ static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw) static inline void uart_ll_set_mode_irda(uart_dev_t *hw) { hw->rs485_conf_sync.rs485_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.rs485tx_rx_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->rs485_conf_sync.rs485rxby_tx_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.sw_rts = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->conf0_sync.irda_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -809,9 +820,9 @@ static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num) { *cmd_char = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, data); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); *char_num = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, char_num); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -886,15 +897,16 @@ static inline bool uart_ll_is_hw_cts_en(uart_dev_t *hw) static inline void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en) { hw->conf0_sync.loopback = loop_back_en; + uart_ll_update(hw); } static inline void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on) { hw->swfc_conf0_sync.force_xon = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); if(!always_on) { hw->swfc_conf0_sync.force_xon = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } } @@ -916,7 +928,7 @@ static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) conf0_reg.rxd_inv = (inv_mask & UART_SIGNAL_RXD_INV) ? 1 : 0; conf0_reg.txd_inv = (inv_mask & UART_SIGNAL_TXD_INV) ? 1 : 0; hw->conf0_sync.val = conf0_reg.val; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); typeof(hw->conf1) conf1_reg; conf1_reg.val = hw->conf1.val; @@ -925,6 +937,7 @@ static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) conf1_reg.cts_inv = (inv_mask & UART_SIGNAL_CTS_INV) ? 1 : 0; conf1_reg.dsr_inv = (inv_mask & UART_SIGNAL_DSR_INV) ? 1 : 0; hw->conf1.val = conf1_reg.val; + uart_ll_update(hw); } /** @@ -940,12 +953,12 @@ static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) uint16_t tout_val = tout_thrd; if(tout_thrd > 0) { hw->tout_conf_sync.rx_tout_thrhd = tout_val; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); hw->tout_conf_sync.rx_tout_en = 1; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } else { hw->tout_conf_sync.rx_tout_en = 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } } @@ -986,7 +999,7 @@ static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw) static inline void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable) { hw->conf0_sync.autobaud_en = enable ? 1 : 0; - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(hw); } /** @@ -1049,10 +1062,9 @@ static inline uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) static inline void uart_ll_force_xoff(uart_port_t uart_num) { REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(UART_LL_GET_HW(uart_num)); REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); - uart_ll_update(0); // TODO: IDF-5338 - // REG_SET_BIT(UART_ID_REG(uart_num), UART_UPDATE); + uart_ll_update(UART_LL_GET_HW(uart_num)); } /** @@ -1065,12 +1077,11 @@ static inline void uart_ll_force_xoff(uart_port_t uart_num) static inline void uart_ll_force_xon(uart_port_t uart_num) { REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XOFF); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(UART_LL_GET_HW(uart_num)); REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); - uart_ll_update(0); // TODO: IDF-5338 + uart_ll_update(UART_LL_GET_HW(uart_num)); REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XON); - uart_ll_update(0); // TODO: IDF-5338 - // REG_SET_BIT(UART_ID_REG(uart_num), UART_UPDATE); + uart_ll_update(UART_LL_GET_HW(uart_num)); } /** diff --git a/components/soc/esp32c6/include/soc/clk_tree_defs.h b/components/soc/esp32c6/include/soc/clk_tree_defs.h index 32c77d1b9d..0408def39b 100644 --- a/components/soc/esp32c6/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c6/include/soc/clk_tree_defs.h @@ -227,7 +227,11 @@ typedef enum { UART_SCLK_APB = SOC_MOD_CLK_APB, /*!< UART source clock is APB CLK */ 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 */ +#if CONFIG_IDF_ENV_FPGA + UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< UART source clock default choice is XTAL for FPGA environment */ +#else UART_SCLK_DEFAULT = SOC_MOD_CLK_APB, /*!< UART source clock default choice is APB */ +#endif } soc_periph_uart_clk_src_legacy_t; //////////////////////////////////////////////////MCPWM///////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32c6/include/soc/uart_struct.h b/components/soc/esp32c6/include/soc/uart_struct.h index d1deab0044..2315f5c1ad 100644 --- a/components/soc/esp32c6/include/soc/uart_struct.h +++ b/components/soc/esp32c6/include/soc/uart_struct.h @@ -16,7 +16,7 @@ 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:32; From 888ca08cb211bfe0978712ca5552b8278e06570b Mon Sep 17 00:00:00 2001 From: laokaiyao Date: Tue, 15 Nov 2022 18:22:50 +0800 Subject: [PATCH 3/3] uart: support examples and tests on esp32c6 --- components/driver/.build-test-rules.yml | 6 -- components/driver/uart.c | 5 + components/hal/esp32c6/include/hal/uart_ll.h | 100 ++++++------------ .../esp32c6/include/soc/Kconfig.soc_caps.in | 8 +- .../soc/esp32c6/include/soc/clk_tree_defs.h | 10 +- components/soc/esp32c6/include/soc/soc_caps.h | 7 +- .../soc/esp32c6/include/soc/uart_channel.h | 12 +-- docs/docs_not_updated/esp32c6.txt | 1 - examples/peripherals/.build-test-rules.yml | 10 -- examples/peripherals/uart/uart_echo/README.md | 4 +- .../uart/uart_echo/main/Kconfig.projbuild | 4 +- .../uart/uart_echo_rs485/README.md | 7 +- .../uart_echo_rs485/main/Kconfig.projbuild | 4 +- 13 files changed, 62 insertions(+), 116 deletions(-) diff --git a/components/driver/.build-test-rules.yml b/components/driver/.build-test-rules.yml index 9923237f72..84d13b4918 100644 --- a/components/driver/.build-test-rules.yml +++ b/components/driver/.build-test-rules.yml @@ -88,9 +88,3 @@ components/driver/test_apps/touch_sensor_v2: components/driver/test_apps/twai: disable: - if: SOC_TWAI_SUPPORTED != 1 - -components/driver/test_apps/uart: - disable_test: - - if: IDF_TARGET == "esp32c6" - temporary: true - reason: target esp32c6 not supported yet diff --git a/components/driver/uart.c b/components/driver/uart.c index 302ccbccde..a378765119 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -232,6 +232,11 @@ esp_err_t uart_get_sclk_freq(uart_sclk_t sclk, uint32_t* out_freq_hz) case UART_SCLK_XTAL: freq = esp_clk_xtal_freq(); break; +#endif +#if SOC_UART_SUPPORT_PLL_F80M_CLK + case UART_SCLK_PLL_F80M: + freq = UART_LL_PLL_DIV_FREQ; + break; #endif default: return ESP_ERR_INVALID_ARG; diff --git a/components/hal/esp32c6/include/hal/uart_ll.h b/components/hal/esp32c6/include/hal/uart_ll.h index 372d3aeff4..543ebfcbda 100644 --- a/components/hal/esp32c6/include/hal/uart_ll.h +++ b/components/hal/esp32c6/include/hal/uart_ll.h @@ -31,6 +31,20 @@ extern "C" { #define UART_LL_FSM_IDLE (0x0) #define UART_LL_FSM_TX_WAIT_SEND (0xf) +#define UART_LL_PLL_DIV_FREQ (80000000) // 80 MHz + +#define UART_LL_PCR_REG_U32_SET(hw, reg_suffix, field_suffix, val) \ + if ((hw) == &UART0) { \ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.uart0_##reg_suffix, uart0_##field_suffix, (val)) \ + } else { \ + HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.uart1_##reg_suffix, uart1_##field_suffix, (val)) \ + } + +#define UART_LL_PCR_REG_U32_GET(hw, reg_suffix, field_suffix) \ + (((hw) == &UART0) ? \ + HAL_FORCE_READ_U32_REG_FIELD(PCR.uart0_##reg_suffix, uart0_##field_suffix) : \ + HAL_FORCE_READ_U32_REG_FIELD(PCR.uart1_##reg_suffix, uart1_##field_suffix)) + #define UART_LL_PCR_REG_SET(hw, reg_suffix, field_suffix, val) \ if ((hw) == &UART0) { \ PCR.uart0_##reg_suffix.uart0_##field_suffix = (val); \ @@ -62,14 +76,21 @@ typedef enum { UART_INTR_RS485_FRM_ERR = (0x1 << 16), UART_INTR_RS485_CLASH = (0x1 << 17), UART_INTR_CMD_CHAR_DET = (0x1 << 18), - // UART_INTR_WAKEUP = (0x1 << 19), // TODO: IDF-5338 + // UART_INTR_WAKEUP = (0x1 << 19), // TODO: Test UART wakeup while supporting sleep } uart_intr_t; +/** + * @brief Sync the update to UART core clock domain + * + * @param hw Beginning address of the peripheral registers. + * + * @return None. + */ static inline void uart_ll_update(uart_dev_t *hw) { // TODO: set a timeout ?? - while (hw->reg_update.reg_update); hw->reg_update.reg_update = 1; + while (hw->reg_update.reg_update); } /** @@ -82,7 +103,7 @@ static inline void uart_ll_update(uart_dev_t *hw) */ static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) { - UART_LL_PCR_REG_SET(hw, conf, rst_en, core_rst_en); + hw->clk_conf.rst_core = core_rst_en; } /** @@ -94,7 +115,6 @@ static inline void uart_ll_set_reset_core(uart_dev_t *hw, bool core_rst_en) */ static inline void uart_ll_sclk_enable(uart_dev_t *hw) { - UART_LL_PCR_REG_SET(hw, conf, clk_en, 1); UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1); } @@ -107,7 +127,6 @@ static inline void uart_ll_sclk_enable(uart_dev_t *hw) */ static inline void uart_ll_sclk_disable(uart_dev_t *hw) { - UART_LL_PCR_REG_SET(hw, conf, clk_en, 0); UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0); } @@ -124,7 +143,7 @@ static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk) { switch (source_clk) { default: - case UART_SCLK_APB: + case UART_SCLK_PLL_F80M: UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 1); break; case UART_SCLK_RTC: @@ -149,7 +168,7 @@ static inline void uart_ll_get_sclk(uart_dev_t *hw, uart_sclk_t *source_clk) switch (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_sel)) { default: case 1: - *source_clk = UART_SCLK_APB; + *source_clk = UART_SCLK_PLL_F80M; break; case 2: *source_clk = UART_SCLK_RTC; @@ -180,7 +199,7 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t // an integer part and a fractional part. hw->clkdiv_sync.clkdiv_int = clk_div >> 4; hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf; - UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1); + UART_LL_PCR_REG_U32_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1); #undef DIV_UP uart_ll_update(hw); } @@ -197,7 +216,7 @@ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) { typeof(hw->clkdiv_sync) div_reg; div_reg.val = hw->clkdiv_sync.val; - return ((sclk_freq << 4)) / (((div_reg.clkdiv_int << 4) | div_reg.clkdiv_frag) * (UART_LL_PCR_REG_GET(hw, sclk_conf, sclk_div_num) + 1)); + return ((sclk_freq << 4)) / (((div_reg.clkdiv_int << 4) | div_reg.clkdiv_frag) * (UART_LL_PCR_REG_U32_GET(hw, sclk_conf, sclk_div_num) + 1)); } /** @@ -211,7 +230,6 @@ static inline uint32_t uart_ll_get_baudrate(uart_dev_t *hw, uint32_t sclk_freq) static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) { hw->int_ena.val |= mask; - uart_ll_update(hw); } /** @@ -225,7 +243,6 @@ static inline void uart_ll_ena_intr_mask(uart_dev_t *hw, uint32_t mask) static inline void uart_ll_disable_intr_mask(uart_dev_t *hw, uint32_t mask) { hw->int_ena.val &= (~mask); - uart_ll_update(hw); } /** @@ -251,7 +268,6 @@ static inline uint32_t uart_ll_get_intsts_mask(uart_dev_t *hw) static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask) { hw->int_clr.val = mask; - uart_ll_update(hw); } /** @@ -425,7 +441,6 @@ static inline void uart_ll_get_parity(uart_dev_t *hw, uart_parity_t *parity_mode static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thrhd) { hw->conf1.rxfifo_full_thrhd = full_thrhd; - uart_ll_update(hw); } /** @@ -440,7 +455,6 @@ static inline void uart_ll_set_rxfifo_full_thr(uart_dev_t *hw, uint16_t full_thr static inline void uart_ll_set_txfifo_empty_thr(uart_dev_t *hw, uint16_t empty_thrhd) { hw->conf1.txfifo_empty_thrhd = empty_thrhd; - uart_ll_update(hw); } /** @@ -484,13 +498,11 @@ static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num) { if (break_num > 0) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->txbrk_conf_sync, tx_brk_num, break_num); - uart_ll_update(hw); hw->conf0_sync.txd_brk = 1; - uart_ll_update(hw); } else { hw->conf0_sync.txd_brk = 0; - uart_ll_update(hw); } + uart_ll_update(hw); } /** @@ -507,20 +519,16 @@ static inline void uart_ll_set_hw_flow_ctrl(uart_dev_t *hw, uart_hw_flowcontrol_ //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; - uart_ll_update(hw); hw->hwfc_conf_sync.rx_flow_en = 1; - uart_ll_update(hw); } else { hw->hwfc_conf_sync.rx_flow_en = 0; - uart_ll_update(hw); } if (flow_ctrl & UART_HW_FLOWCTRL_CTS) { hw->conf0_sync.tx_flow_en = 1; - uart_ll_update(hw); } else { hw->conf0_sync.tx_flow_en = 0; - uart_ll_update(hw); } + uart_ll_update(hw); } /** @@ -555,21 +563,16 @@ static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t * { if (sw_flow_ctrl_en) { hw->swfc_conf0_sync.xonoff_del = 1; - uart_ll_update(hw); hw->swfc_conf0_sync.sw_flow_con_en = 1; - uart_ll_update(hw); 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); - uart_ll_update(hw); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xoff_char, flow_ctrl->xoff_char); - uart_ll_update(hw); } else { hw->swfc_conf0_sync.sw_flow_con_en = 0; - uart_ll_update(hw); hw->swfc_conf0_sync.xonoff_del = 0; - uart_ll_update(hw); } + uart_ll_update(hw); } /** @@ -588,13 +591,9 @@ static inline void uart_ll_set_sw_flow_ctrl(uart_dev_t *hw, uart_sw_flowctrl_t * static inline void uart_ll_set_at_cmd_char(uart_dev_t *hw, uart_at_cmd_t *cmd_char) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, data, cmd_char->cmd_char); - uart_ll_update(hw); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, char_num, cmd_char->char_num); - uart_ll_update(hw); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_postcnt_sync, post_idle_num, cmd_char->post_idle); - uart_ll_update(hw); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_precnt_sync, pre_idle_num, cmd_char->pre_idle); - uart_ll_update(hw); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_gaptout_sync, rx_gap_tout, cmd_char->gap_tout); uart_ll_update(hw); } @@ -638,7 +637,6 @@ static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level) static inline void uart_ll_set_dtr_active_level(uart_dev_t *hw, int level) { hw->conf1.sw_dtr = level & 0x1; - uart_ll_update(hw); } /** @@ -653,7 +651,6 @@ 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) { hw->sleep_conf2.active_threshold = wakeup_thrd - UART_LL_MIN_WAKEUP_THRESH; - uart_ll_update(hw); } /** @@ -666,11 +663,8 @@ static inline void uart_ll_set_wakeup_thrd(uart_dev_t *hw, uint32_t wakeup_thrd) static inline void uart_ll_set_mode_normal(uart_dev_t *hw) { hw->rs485_conf_sync.rs485_en = 0; - uart_ll_update(hw); hw->rs485_conf_sync.rs485tx_rx_en = 0; - uart_ll_update(hw); hw->rs485_conf_sync.rs485rxby_tx_en = 0; - uart_ll_update(hw); hw->conf0_sync.irda_en = 0; uart_ll_update(hw); } @@ -686,17 +680,11 @@ static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw) { // Application software control, remove echo hw->rs485_conf_sync.rs485rxby_tx_en = 1; - uart_ll_update(hw); hw->conf0_sync.irda_en = 0; - uart_ll_update(hw); hw->conf0_sync.sw_rts = 0; - uart_ll_update(hw); hw->conf0_sync.irda_en = 0; - uart_ll_update(hw); hw->rs485_conf_sync.dl0_en = 1; - uart_ll_update(hw); hw->rs485_conf_sync.dl1_en = 1; - uart_ll_update(hw); hw->rs485_conf_sync.rs485_en = 1; uart_ll_update(hw); } @@ -712,20 +700,14 @@ static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) { // Enable receiver, sw_rts = 1 generates low level on RTS pin hw->conf0_sync.sw_rts = 1; - uart_ll_update(hw); // Half duplex mode hw->rs485_conf_sync.rs485tx_rx_en = 0; - uart_ll_update(hw); // Setting this bit will allow data to be transmitted while receiving data(full-duplex mode). // But note that this full-duplex mode has no conflict detection function hw->rs485_conf_sync.rs485rxby_tx_en = 0; - uart_ll_update(hw); hw->conf0_sync.irda_en = 0; - uart_ll_update(hw); hw->rs485_conf_sync.dl0_en = 1; - uart_ll_update(hw); hw->rs485_conf_sync.dl1_en = 1; - uart_ll_update(hw); hw->rs485_conf_sync.rs485_en = 1; uart_ll_update(hw); } @@ -740,19 +722,13 @@ static inline void uart_ll_set_mode_rs485_half_duplex(uart_dev_t *hw) static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw) { hw->conf0_sync.irda_en = 0; - uart_ll_update(hw); // Enable full-duplex mode hw->rs485_conf_sync.rs485tx_rx_en = 1; - uart_ll_update(hw); // Transmitter should send data when the receiver is busy, hw->rs485_conf_sync.rs485rxby_tx_en = 1; - uart_ll_update(hw); hw->rs485_conf_sync.dl0_en = 1; - uart_ll_update(hw); hw->rs485_conf_sync.dl1_en = 1; - uart_ll_update(hw); hw->conf0_sync.sw_rts = 0; - uart_ll_update(hw); hw->rs485_conf_sync.rs485_en = 1; uart_ll_update(hw); } @@ -767,13 +743,9 @@ static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw) static inline void uart_ll_set_mode_irda(uart_dev_t *hw) { hw->rs485_conf_sync.rs485_en = 0; - uart_ll_update(hw); hw->rs485_conf_sync.rs485tx_rx_en = 0; - uart_ll_update(hw); hw->rs485_conf_sync.rs485rxby_tx_en = 0; - uart_ll_update(hw); hw->conf0_sync.sw_rts = 0; - uart_ll_update(hw); hw->conf0_sync.irda_en = 1; uart_ll_update(hw); } @@ -820,9 +792,7 @@ static inline void uart_ll_set_mode(uart_dev_t *hw, uart_mode_t mode) static inline void uart_ll_get_at_cmd_char(uart_dev_t *hw, uint8_t *cmd_char, uint8_t *char_num) { *cmd_char = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, data); - uart_ll_update(hw); *char_num = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, char_num); - uart_ll_update(hw); } /** @@ -928,7 +898,6 @@ static inline void uart_ll_inverse_signal(uart_dev_t *hw, uint32_t inv_mask) conf0_reg.rxd_inv = (inv_mask & UART_SIGNAL_RXD_INV) ? 1 : 0; conf0_reg.txd_inv = (inv_mask & UART_SIGNAL_TXD_INV) ? 1 : 0; hw->conf0_sync.val = conf0_reg.val; - uart_ll_update(hw); typeof(hw->conf1) conf1_reg; conf1_reg.val = hw->conf1.val; @@ -953,13 +922,11 @@ static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd) uint16_t tout_val = tout_thrd; if(tout_thrd > 0) { hw->tout_conf_sync.rx_tout_thrhd = tout_val; - uart_ll_update(hw); hw->tout_conf_sync.rx_tout_en = 1; - uart_ll_update(hw); } else { hw->tout_conf_sync.rx_tout_en = 0; - uart_ll_update(hw); } + uart_ll_update(hw); } /** @@ -1062,7 +1029,6 @@ static inline uint32_t uart_ll_get_low_pulse_cnt(uart_dev_t *hw) static inline void uart_ll_force_xoff(uart_port_t uart_num) { REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); - uart_ll_update(UART_LL_GET_HW(uart_num)); REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); uart_ll_update(UART_LL_GET_HW(uart_num)); } @@ -1077,9 +1043,7 @@ static inline void uart_ll_force_xoff(uart_port_t uart_num) static inline void uart_ll_force_xon(uart_port_t uart_num) { REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XOFF); - uart_ll_update(UART_LL_GET_HW(uart_num)); REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); - uart_ll_update(UART_LL_GET_HW(uart_num)); REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XON); uart_ll_update(UART_LL_GET_HW(uart_num)); } diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index c3d9c9e1bc..35804883c6 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -807,19 +807,15 @@ config SOC_UART_BITRATE_MAX int default 5000000 -config SOC_UART_SUPPORT_APB_CLK +config SOC_UART_SUPPORT_PLL_F80M_CLK bool default y config SOC_UART_SUPPORT_RTC_CLK - bool - default n - -config SOC_UART_SUPPORT_XTAL_CLK bool default y -config SOC_UART_REQUIRE_CORE_RESET +config SOC_UART_SUPPORT_XTAL_CLK bool default y diff --git a/components/soc/esp32c6/include/soc/clk_tree_defs.h b/components/soc/esp32c6/include/soc/clk_tree_defs.h index 0408def39b..ccd0d25f41 100644 --- a/components/soc/esp32c6/include/soc/clk_tree_defs.h +++ b/components/soc/esp32c6/include/soc/clk_tree_defs.h @@ -224,13 +224,13 @@ typedef enum { * @brief Type of UART clock source, reserved for the legacy UART driver */ typedef enum { - UART_SCLK_APB = SOC_MOD_CLK_APB, /*!< UART source clock is APB CLK */ - 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_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock is PLL_F80M */ + 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 */ #if CONFIG_IDF_ENV_FPGA - UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< UART source clock default choice is XTAL for FPGA environment */ + UART_SCLK_DEFAULT = SOC_MOD_CLK_XTAL, /*!< UART source clock default choice is XTAL for FPGA environment */ #else - UART_SCLK_DEFAULT = SOC_MOD_CLK_APB, /*!< UART source clock default choice is APB */ + UART_SCLK_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */ #endif } soc_periph_uart_clk_src_legacy_t; diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index d1ed6f241f..093ab09513 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -393,11 +393,10 @@ #define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ #define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ -#define SOC_UART_SUPPORT_APB_CLK (1) /*!< Support APB as the clock source */ -#define SOC_UART_SUPPORT_RTC_CLK (0) /*!< Support RTC clock as the clock source */ // TODO: IDF-5338 +#define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_DIV as the clock source */ +#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ #define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ -// #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ // TODO: IDF-5338 -#define SOC_UART_REQUIRE_CORE_RESET (1) +// #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ // TODO: Test UART wakeup while supporting sleep // 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) diff --git a/components/soc/esp32c6/include/soc/uart_channel.h b/components/soc/esp32c6/include/soc/uart_channel.h index b81bfc432d..507f020603 100644 --- a/components/soc/esp32c6/include/soc/uart_channel.h +++ b/components/soc/esp32c6/include/soc/uart_channel.h @@ -10,12 +10,12 @@ #define _SOC_UART_CHANNEL_H //UART channels -#define UART_GPIO21_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 21 -#define UART_GPIO20_DIRECT_CHANNEL UART_NUM_0 -#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 20 +#define UART_GPIO16_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 16 +#define UART_GPIO17_DIRECT_CHANNEL UART_NUM_0 +#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 17 -#define UART_TXD_GPIO21_DIRECT_CHANNEL UART_GPIO21_DIRECT_CHANNEL -#define UART_RXD_GPIO20_DIRECT_CHANNEL UART_GPIO20_DIRECT_CHANNEL +#define UART_TXD_GPIO16_DIRECT_CHANNEL UART_GPIO16_DIRECT_CHANNEL +#define UART_RXD_GPIO17_DIRECT_CHANNEL UART_GPIO17_DIRECT_CHANNEL #endif diff --git a/docs/docs_not_updated/esp32c6.txt b/docs/docs_not_updated/esp32c6.txt index a135eacbe5..ad6c69f528 100644 --- a/docs/docs_not_updated/esp32c6.txt +++ b/docs/docs_not_updated/esp32c6.txt @@ -113,7 +113,6 @@ api-reference/peripherals/ds api-reference/peripherals/sd_pullup_requirements api-reference/peripherals/index api-reference/peripherals/sdmmc_host -api-reference/peripherals/uart api-reference/kconfig api-reference/network api-reference/network/esp_openthread diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index a2c07640f1..f5af80c04a 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -238,19 +238,9 @@ examples/peripherals/twai/twai_self_test: temporary: true reason: lack of runners -examples/peripherals/uart/uart_echo: - disable: - - if: IDF_TARGET == "esp32c6" - temporary: true - reason: target esp32c6 is not supported yet - examples/peripherals/uart/uart_echo_rs485: enable: - if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "esp32h4" - disable: - - if: IDF_TARGET == "esp32c6" - temporary: true - reason: target esp32c6 is not supported yet examples/peripherals/usb: disable: diff --git a/examples/peripherals/uart/uart_echo/README.md b/examples/peripherals/uart/uart_echo/README.md index 80e05bbbff..8dce28fb59 100644 --- a/examples/peripherals/uart/uart_echo/README.md +++ b/examples/peripherals/uart/uart_echo/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | # UART Echo Example diff --git a/examples/peripherals/uart/uart_echo/main/Kconfig.projbuild b/examples/peripherals/uart/uart_echo/main/Kconfig.projbuild index 0959ec7aba..573604b107 100644 --- a/examples/peripherals/uart/uart_echo/main/Kconfig.projbuild +++ b/examples/peripherals/uart/uart_echo/main/Kconfig.projbuild @@ -6,8 +6,8 @@ menu "Echo Example Configuration" int "UART port number" range 0 2 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 default 2 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 - range 0 1 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H4 - default 1 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H4 + range 0 1 + default 1 help UART communication port number for the example. See UART documentation for available port numbers. diff --git a/examples/peripherals/uart/uart_echo_rs485/README.md b/examples/peripherals/uart/uart_echo_rs485/README.md index e41602d749..70d834e9f9 100644 --- a/examples/peripherals/uart/uart_echo_rs485/README.md +++ b/examples/peripherals/uart/uart_echo_rs485/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-H4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | # UART RS485 Echo Example @@ -36,8 +36,7 @@ ESP32 BOARD | | RS-485 side | | SERIAL AD Connect a USB-to-RS485 adapter to a computer, then connect the adapter's A/B output lines with the corresponding A/B output lines of the RS485 line driver connected to the ESP32 chip (see figure above). ``` ------------------------------------------------------------------------------------------------------------------------------ - | UART Interface | #define | Default ESP32 Pin | Default pins for | External RS485 Driver Pin | - | | | | ESP32-S2(S3, C3, C2, H4) | | + | UART Interface | #define | Default pin for ESP32 | Default pins for others | External RS485 Driver Pin | | ----------------------|--------------------|-----------------------|---------------------------|---------------------------| | Transmit Data (TxD) | CONFIG_MB_UART_TXD | GPIO23 | GPIO9 | DI | | Receive Data (RxD) | CONFIG_MB_UART_RXD | GPIO22 | GPIO8 | RO | diff --git a/examples/peripherals/uart/uart_echo_rs485/main/Kconfig.projbuild b/examples/peripherals/uart/uart_echo_rs485/main/Kconfig.projbuild index d9e7f85e82..786e2ad39b 100644 --- a/examples/peripherals/uart/uart_echo_rs485/main/Kconfig.projbuild +++ b/examples/peripherals/uart/uart_echo_rs485/main/Kconfig.projbuild @@ -6,8 +6,8 @@ menu "Echo RS485 Example Configuration" int "UART port number" range 0 2 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 default 2 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 - range 0 1 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H4 - default 1 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H4 + range 0 1 + default 1 help UART communication port number for the example. See UART documentation for available port numbers.