Merge branch 'feature/support_uart_on_c6' into 'master'

uart: support uart on esp32c6

Closes IDF-5338

See merge request espressif/esp-idf!21101
This commit is contained in:
Kevin (Lao Kaiyao)
2022-11-24 18:42:31 +08:00
14 changed files with 111 additions and 151 deletions

View File

@@ -88,9 +88,3 @@ components/driver/test_apps/touch_sensor_v2:
components/driver/test_apps/twai: components/driver/test_apps/twai:
disable: disable:
- if: SOC_TWAI_SUPPORTED != 1 - if: SOC_TWAI_SUPPORTED != 1
components/driver/test_apps/uart:
disable_test:
- if: IDF_TARGET == "esp32c6"
temporary: true
reason: target esp32c6 not supported yet

View File

@@ -232,6 +232,11 @@ esp_err_t uart_get_sclk_freq(uart_sclk_t sclk, uint32_t* out_freq_hz)
case UART_SCLK_XTAL: case UART_SCLK_XTAL:
freq = esp_clk_xtal_freq(); freq = esp_clk_xtal_freq();
break; break;
#endif
#if SOC_UART_SUPPORT_PLL_F80M_CLK
case UART_SCLK_PLL_F80M:
freq = UART_LL_PLL_DIV_FREQ;
break;
#endif #endif
default: default:
return ESP_ERR_INVALID_ARG; return ESP_ERR_INVALID_ARG;

View File

@@ -14,6 +14,7 @@
#include "hal/uart_types.h" #include "hal/uart_types.h"
#include "soc/uart_periph.h" #include "soc/uart_periph.h"
#include "soc/uart_struct.h" #include "soc/uart_struct.h"
#include "soc/pcr_struct.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@@ -30,6 +31,30 @@ extern "C" {
#define UART_LL_FSM_IDLE (0x0) #define UART_LL_FSM_IDLE (0x0)
#define UART_LL_FSM_TX_WAIT_SEND (0xf) #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); \
} 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 // Define UART interrupts
typedef enum { typedef enum {
UART_INTR_RXFIFO_FULL = (0x1 << 0), UART_INTR_RXFIFO_FULL = (0x1 << 0),
@@ -51,19 +76,21 @@ typedef enum {
UART_INTR_RS485_FRM_ERR = (0x1 << 16), UART_INTR_RS485_FRM_ERR = (0x1 << 16),
UART_INTR_RS485_CLASH = (0x1 << 17), UART_INTR_RS485_CLASH = (0x1 << 17),
UART_INTR_CMD_CHAR_DET = (0x1 << 18), 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; } uart_intr_t;
static inline void uart_ll_update(int uart_no) // TODO: IDF-5338 should use uart_dev_t *hw /**
* @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 ?? // TODO: set a timeout ??
while(1) { hw->reg_update.reg_update = 1;
int update = GET_PERI_REG_BITS2(UART_REG_UPDATE_REG(uart_no), UART_REG_UPDATE_V, UART_REG_UPDATE_S); while (hw->reg_update.reg_update);
if (!update) {
break;
}
}
SET_PERI_REG_MASK(UART_REG_UPDATE_REG(uart_no), UART_REG_UPDATE_M);
} }
/** /**
@@ -88,9 +115,7 @@ 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) static inline void uart_ll_sclk_enable(uart_dev_t *hw)
{ {
hw->clk_conf.sclk_en = 1; UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 1);
hw->clk_conf.rx_sclk_en = 1;
hw->clk_conf.tx_sclk_en = 1;
} }
/** /**
@@ -102,9 +127,7 @@ static inline void uart_ll_sclk_enable(uart_dev_t *hw)
*/ */
static inline void uart_ll_sclk_disable(uart_dev_t *hw) static inline void uart_ll_sclk_disable(uart_dev_t *hw)
{ {
hw->clk_conf.sclk_en = 0; UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_en, 0);
hw->clk_conf.rx_sclk_en = 0;
hw->clk_conf.tx_sclk_en = 0;
} }
/** /**
@@ -120,14 +143,14 @@ static inline void uart_ll_set_sclk(uart_dev_t *hw, uart_sclk_t source_clk)
{ {
switch (source_clk) { switch (source_clk) {
default: default:
case UART_SCLK_APB: case UART_SCLK_PLL_F80M:
hw->clk_conf.sclk_sel = 1; UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 1);
break; break;
case UART_SCLK_RTC: case UART_SCLK_RTC:
hw->clk_conf.sclk_sel = 2; UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 2);
break; break;
case UART_SCLK_XTAL: case UART_SCLK_XTAL:
hw->clk_conf.sclk_sel = 3; UART_LL_PCR_REG_SET(hw, sclk_conf, sclk_sel, 3);
break; break;
} }
} }
@@ -142,10 +165,10 @@ 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) 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: default:
case 1: case 1:
*source_clk = UART_SCLK_APB; *source_clk = UART_SCLK_PLL_F80M;
break; break;
case 2: case 2:
*source_clk = UART_SCLK_RTC; *source_clk = UART_SCLK_RTC;
@@ -176,9 +199,9 @@ static inline void uart_ll_set_baudrate(uart_dev_t *hw, uint32_t baud, uint32_t
// an integer part and a fractional part. // an integer part and a fractional part.
hw->clkdiv_sync.clkdiv_int = clk_div >> 4; hw->clkdiv_sync.clkdiv_int = clk_div >> 4;
hw->clkdiv_sync.clkdiv_frag = clk_div & 0xf; 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_U32_SET(hw, sclk_conf, sclk_div_num, sclk_div - 1);
#undef DIV_UP #undef DIV_UP
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -193,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; typeof(hw->clkdiv_sync) div_reg;
div_reg.val = hw->clkdiv_sync.val; 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_U32_GET(hw, sclk_conf, sclk_div_num) + 1));
} }
/** /**
@@ -271,7 +294,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) 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++) { 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 +310,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) 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++) { 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];
} }
} }
@@ -301,9 +324,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) static inline void uart_ll_rxfifo_rst(uart_dev_t *hw)
{ {
hw->conf0_sync.rxfifo_rst = 1; hw->conf0_sync.rxfifo_rst = 1;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
hw->conf0_sync.rxfifo_rst = 0; hw->conf0_sync.rxfifo_rst = 0;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -316,9 +339,9 @@ static inline void uart_ll_rxfifo_rst(uart_dev_t *hw)
static inline void uart_ll_txfifo_rst(uart_dev_t *hw) static inline void uart_ll_txfifo_rst(uart_dev_t *hw)
{ {
hw->conf0_sync.txfifo_rst = 1; hw->conf0_sync.txfifo_rst = 1;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
hw->conf0_sync.txfifo_rst = 0; hw->conf0_sync.txfifo_rst = 0;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -356,7 +379,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) 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; hw->conf0_sync.stop_bit_num = stop_bit;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -386,7 +409,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 = parity_mode & 0x1;
} }
hw->conf0_sync.parity_en = (parity_mode >> 1) & 0x1; hw->conf0_sync.parity_en = (parity_mode >> 1) & 0x1;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -446,7 +469,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) 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; hw->idle_conf_sync.rx_idle_thrhd = rx_idle_thr;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -460,7 +483,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) 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; hw->idle_conf_sync.tx_idle_num = idle_num;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -475,13 +498,11 @@ static inline void uart_ll_tx_break(uart_dev_t *hw, uint32_t break_num)
{ {
if (break_num > 0) { if (break_num > 0) {
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->txbrk_conf_sync, tx_brk_num, break_num); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->txbrk_conf_sync, tx_brk_num, break_num);
uart_ll_update(0); // TODO: IDF-5338
hw->conf0_sync.txd_brk = 1; hw->conf0_sync.txd_brk = 1;
uart_ll_update(0); // TODO: IDF-5338
} else { } else {
hw->conf0_sync.txd_brk = 0; hw->conf0_sync.txd_brk = 0;
uart_ll_update(0); // TODO: IDF-5338
} }
uart_ll_update(hw);
} }
/** /**
@@ -498,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. //only when UART_HW_FLOWCTRL_RTS is set , will the rx_thresh value be set.
if (flow_ctrl & UART_HW_FLOWCTRL_RTS) { if (flow_ctrl & UART_HW_FLOWCTRL_RTS) {
hw->hwfc_conf_sync.rx_flow_thrhd = rx_thrs; hw->hwfc_conf_sync.rx_flow_thrhd = rx_thrs;
uart_ll_update(0); // TODO: IDF-5338
hw->hwfc_conf_sync.rx_flow_en = 1; hw->hwfc_conf_sync.rx_flow_en = 1;
uart_ll_update(0); // TODO: IDF-5338
} else { } else {
hw->hwfc_conf_sync.rx_flow_en = 0; hw->hwfc_conf_sync.rx_flow_en = 0;
uart_ll_update(0); // TODO: IDF-5338
} }
if (flow_ctrl & UART_HW_FLOWCTRL_CTS) { if (flow_ctrl & UART_HW_FLOWCTRL_CTS) {
hw->conf0_sync.tx_flow_en = 1; hw->conf0_sync.tx_flow_en = 1;
uart_ll_update(0); // TODO: IDF-5338
} else { } else {
hw->conf0_sync.tx_flow_en = 0; hw->conf0_sync.tx_flow_en = 0;
uart_ll_update(0); // TODO: IDF-5338
} }
uart_ll_update(hw);
} }
/** /**
@@ -546,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) { if (sw_flow_ctrl_en) {
hw->swfc_conf0_sync.xonoff_del = 1; hw->swfc_conf0_sync.xonoff_del = 1;
uart_ll_update(0); // TODO: IDF-5338
hw->swfc_conf0_sync.sw_flow_con_en = 1; hw->swfc_conf0_sync.sw_flow_con_en = 1;
uart_ll_update(0); // TODO: IDF-5338
hw->swfc_conf1.xon_threshold = flow_ctrl->xon_thrd; hw->swfc_conf1.xon_threshold = flow_ctrl->xon_thrd;
hw->swfc_conf1.xoff_threshold = flow_ctrl->xoff_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, xon_char, flow_ctrl->xon_char);
uart_ll_update(0); // TODO: IDF-5338
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xoff_char, flow_ctrl->xoff_char); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->swfc_conf0_sync, xoff_char, flow_ctrl->xoff_char);
uart_ll_update(0); // TODO: IDF-5338
} else { } else {
hw->swfc_conf0_sync.sw_flow_con_en = 0; hw->swfc_conf0_sync.sw_flow_con_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->swfc_conf0_sync.xonoff_del = 0; hw->swfc_conf0_sync.xonoff_del = 0;
uart_ll_update(0); // TODO: IDF-5338
} }
uart_ll_update(hw);
} }
/** /**
@@ -579,15 +591,11 @@ 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) 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); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, data, cmd_char->cmd_char);
uart_ll_update(0); // TODO: IDF-5338
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, char_num, cmd_char->char_num); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_char_sync, char_num, cmd_char->char_num);
uart_ll_update(0); // TODO: IDF-5338
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_postcnt_sync, post_idle_num, cmd_char->post_idle); 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
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_precnt_sync, pre_idle_num, cmd_char->pre_idle); 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
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->at_cmd_gaptout_sync, rx_gap_tout, cmd_char->gap_tout); 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 +609,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) 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; hw->conf0_sync.bit_num = data_bit;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -615,7 +623,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) static inline void uart_ll_set_rts_active_level(uart_dev_t *hw, int level)
{ {
hw->conf0_sync.sw_rts = level & 0x1; hw->conf0_sync.sw_rts = level & 0x1;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -655,13 +663,10 @@ 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) static inline void uart_ll_set_mode_normal(uart_dev_t *hw)
{ {
hw->rs485_conf_sync.rs485_en = 0; hw->rs485_conf_sync.rs485_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.rs485tx_rx_en = 0; hw->rs485_conf_sync.rs485tx_rx_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.rs485rxby_tx_en = 0; hw->rs485_conf_sync.rs485rxby_tx_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->conf0_sync.irda_en = 0; hw->conf0_sync.irda_en = 0;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -675,19 +680,13 @@ static inline void uart_ll_set_mode_rs485_app_ctrl(uart_dev_t *hw)
{ {
// Application software control, remove echo // Application software control, remove echo
hw->rs485_conf_sync.rs485rxby_tx_en = 1; hw->rs485_conf_sync.rs485rxby_tx_en = 1;
uart_ll_update(0); // TODO: IDF-5338
hw->conf0_sync.irda_en = 0; hw->conf0_sync.irda_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->conf0_sync.sw_rts = 0; hw->conf0_sync.sw_rts = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->conf0_sync.irda_en = 0; hw->conf0_sync.irda_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.dl0_en = 1; hw->rs485_conf_sync.dl0_en = 1;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.dl1_en = 1; hw->rs485_conf_sync.dl1_en = 1;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.rs485_en = 1; hw->rs485_conf_sync.rs485_en = 1;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -701,22 +700,16 @@ 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 // Enable receiver, sw_rts = 1 generates low level on RTS pin
hw->conf0_sync.sw_rts = 1; hw->conf0_sync.sw_rts = 1;
uart_ll_update(0); // TODO: IDF-5338
// Half duplex mode // Half duplex mode
hw->rs485_conf_sync.rs485tx_rx_en = 0; hw->rs485_conf_sync.rs485tx_rx_en = 0;
uart_ll_update(0); // TODO: IDF-5338
// Setting this bit will allow data to be transmitted while receiving data(full-duplex mode). // 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 // But note that this full-duplex mode has no conflict detection function
hw->rs485_conf_sync.rs485rxby_tx_en = 0; hw->rs485_conf_sync.rs485rxby_tx_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->conf0_sync.irda_en = 0; hw->conf0_sync.irda_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.dl0_en = 1; hw->rs485_conf_sync.dl0_en = 1;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.dl1_en = 1; hw->rs485_conf_sync.dl1_en = 1;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.rs485_en = 1; hw->rs485_conf_sync.rs485_en = 1;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -729,21 +722,15 @@ 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) static inline void uart_ll_set_mode_collision_detect(uart_dev_t *hw)
{ {
hw->conf0_sync.irda_en = 0; hw->conf0_sync.irda_en = 0;
uart_ll_update(0); // TODO: IDF-5338
// Enable full-duplex mode // Enable full-duplex mode
hw->rs485_conf_sync.rs485tx_rx_en = 1; hw->rs485_conf_sync.rs485tx_rx_en = 1;
uart_ll_update(0); // TODO: IDF-5338
// Transmitter should send data when the receiver is busy, // Transmitter should send data when the receiver is busy,
hw->rs485_conf_sync.rs485rxby_tx_en = 1; hw->rs485_conf_sync.rs485rxby_tx_en = 1;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.dl0_en = 1; hw->rs485_conf_sync.dl0_en = 1;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.dl1_en = 1; hw->rs485_conf_sync.dl1_en = 1;
uart_ll_update(0); // TODO: IDF-5338
hw->conf0_sync.sw_rts = 0; hw->conf0_sync.sw_rts = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.rs485_en = 1; hw->rs485_conf_sync.rs485_en = 1;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -756,15 +743,11 @@ 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) static inline void uart_ll_set_mode_irda(uart_dev_t *hw)
{ {
hw->rs485_conf_sync.rs485_en = 0; hw->rs485_conf_sync.rs485_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.rs485tx_rx_en = 0; hw->rs485_conf_sync.rs485tx_rx_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->rs485_conf_sync.rs485rxby_tx_en = 0; hw->rs485_conf_sync.rs485rxby_tx_en = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->conf0_sync.sw_rts = 0; hw->conf0_sync.sw_rts = 0;
uart_ll_update(0); // TODO: IDF-5338
hw->conf0_sync.irda_en = 1; hw->conf0_sync.irda_en = 1;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -809,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) 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); *cmd_char = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, data);
uart_ll_update(0); // TODO: IDF-5338
*char_num = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, char_num); *char_num = HAL_FORCE_READ_U32_REG_FIELD(hw->at_cmd_char_sync, char_num);
uart_ll_update(0); // TODO: IDF-5338
} }
/** /**
@@ -886,15 +867,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) static inline void uart_ll_set_loop_back(uart_dev_t *hw, bool loop_back_en)
{ {
hw->conf0_sync.loopback = 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) static inline void uart_ll_xon_force_on(uart_dev_t *hw, bool always_on)
{ {
hw->swfc_conf0_sync.force_xon = 1; hw->swfc_conf0_sync.force_xon = 1;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
if(!always_on) { if(!always_on) {
hw->swfc_conf0_sync.force_xon = 0; hw->swfc_conf0_sync.force_xon = 0;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
} }
@@ -916,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.rxd_inv = (inv_mask & UART_SIGNAL_RXD_INV) ? 1 : 0;
conf0_reg.txd_inv = (inv_mask & UART_SIGNAL_TXD_INV) ? 1 : 0; conf0_reg.txd_inv = (inv_mask & UART_SIGNAL_TXD_INV) ? 1 : 0;
hw->conf0_sync.val = conf0_reg.val; hw->conf0_sync.val = conf0_reg.val;
uart_ll_update(0); // TODO: IDF-5338
typeof(hw->conf1) conf1_reg; typeof(hw->conf1) conf1_reg;
conf1_reg.val = hw->conf1.val; conf1_reg.val = hw->conf1.val;
@@ -925,6 +906,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.cts_inv = (inv_mask & UART_SIGNAL_CTS_INV) ? 1 : 0;
conf1_reg.dsr_inv = (inv_mask & UART_SIGNAL_DSR_INV) ? 1 : 0; conf1_reg.dsr_inv = (inv_mask & UART_SIGNAL_DSR_INV) ? 1 : 0;
hw->conf1.val = conf1_reg.val; hw->conf1.val = conf1_reg.val;
uart_ll_update(hw);
} }
/** /**
@@ -940,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; 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_thrhd = tout_val;
uart_ll_update(0); // TODO: IDF-5338
hw->tout_conf_sync.rx_tout_en = 1; hw->tout_conf_sync.rx_tout_en = 1;
uart_ll_update(0); // TODO: IDF-5338
} else { } else {
hw->tout_conf_sync.rx_tout_en = 0; hw->tout_conf_sync.rx_tout_en = 0;
uart_ll_update(0); // TODO: IDF-5338
} }
uart_ll_update(hw);
} }
/** /**
@@ -986,7 +966,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) static inline void uart_ll_set_autobaud_en(uart_dev_t *hw, bool enable)
{ {
hw->conf0_sync.autobaud_en = enable ? 1 : 0; hw->conf0_sync.autobaud_en = enable ? 1 : 0;
uart_ll_update(0); // TODO: IDF-5338 uart_ll_update(hw);
} }
/** /**
@@ -1049,10 +1029,8 @@ 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) 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); REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON);
uart_ll_update(0); // TODO: IDF-5338
REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XOFF); 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 uart_ll_update(UART_LL_GET_HW(uart_num));
// REG_SET_BIT(UART_ID_REG(uart_num), UART_UPDATE);
} }
/** /**
@@ -1065,12 +1043,9 @@ static inline void uart_ll_force_xoff(uart_port_t uart_num)
static inline void uart_ll_force_xon(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); REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XOFF);
uart_ll_update(0); // TODO: IDF-5338
REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON); REG_SET_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_FORCE_XON);
uart_ll_update(0); // TODO: IDF-5338
REG_CLR_BIT(UART_SWFC_CONF0_SYNC_REG(uart_num), UART_SW_FLOW_CON_EN | UART_FORCE_XON); 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 uart_ll_update(UART_LL_GET_HW(uart_num));
// REG_SET_BIT(UART_ID_REG(uart_num), UART_UPDATE);
} }
/** /**

View File

@@ -807,19 +807,15 @@ config SOC_UART_BITRATE_MAX
int int
default 5000000 default 5000000
config SOC_UART_SUPPORT_APB_CLK config SOC_UART_SUPPORT_PLL_F80M_CLK
bool bool
default y default y
config SOC_UART_SUPPORT_RTC_CLK config SOC_UART_SUPPORT_RTC_CLK
bool
default n
config SOC_UART_SUPPORT_XTAL_CLK
bool bool
default y default y
config SOC_UART_REQUIRE_CORE_RESET config SOC_UART_SUPPORT_XTAL_CLK
bool bool
default y default y

View File

@@ -224,10 +224,14 @@ typedef enum {
* @brief Type of UART clock source, reserved for the legacy UART driver * @brief Type of UART clock source, reserved for the legacy UART driver
*/ */
typedef enum { typedef enum {
UART_SCLK_APB = SOC_MOD_CLK_APB, /*!< UART source clock is APB CLK */ 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_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_XTAL = SOC_MOD_CLK_XTAL, /*!< UART source clock is XTAL */
UART_SCLK_DEFAULT = SOC_MOD_CLK_APB, /*!< UART source clock default choice is APB */ #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_PLL_F80M, /*!< UART source clock default choice is PLL_F80M */
#endif
} soc_periph_uart_clk_src_legacy_t; } soc_periph_uart_clk_src_legacy_t;
//////////////////////////////////////////////////MCPWM///////////////////////////////////////////////////////////////// //////////////////////////////////////////////////MCPWM/////////////////////////////////////////////////////////////////

View File

@@ -393,11 +393,10 @@
#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ #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_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_PLL_F80M_CLK (1) /*!< Support PLL_DIV 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_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_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_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ // TODO: Test UART wakeup while supporting sleep
#define SOC_UART_REQUIRE_CORE_RESET (1)
// UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled // 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_FSM_TX_WAIT_SEND (1)

View File

@@ -10,12 +10,12 @@
#define _SOC_UART_CHANNEL_H #define _SOC_UART_CHANNEL_H
//UART channels //UART channels
#define UART_GPIO21_DIRECT_CHANNEL UART_NUM_0 #define UART_GPIO16_DIRECT_CHANNEL UART_NUM_0
#define UART_NUM_0_TXD_DIRECT_GPIO_NUM 21 #define UART_NUM_0_TXD_DIRECT_GPIO_NUM 16
#define UART_GPIO20_DIRECT_CHANNEL UART_NUM_0 #define UART_GPIO17_DIRECT_CHANNEL UART_NUM_0
#define UART_NUM_0_RXD_DIRECT_GPIO_NUM 20 #define UART_NUM_0_RXD_DIRECT_GPIO_NUM 17
#define UART_TXD_GPIO21_DIRECT_CHANNEL UART_GPIO21_DIRECT_CHANNEL #define UART_TXD_GPIO16_DIRECT_CHANNEL UART_GPIO16_DIRECT_CHANNEL
#define UART_RXD_GPIO20_DIRECT_CHANNEL UART_GPIO20_DIRECT_CHANNEL #define UART_RXD_GPIO17_DIRECT_CHANNEL UART_GPIO17_DIRECT_CHANNEL
#endif #endif

View File

@@ -16,11 +16,10 @@ extern "C" {
*/ */
typedef union { typedef union {
struct { 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. * UART $n accesses FIFO via this register.
*/ */
uint32_t rxfifo_rd_byte:8; uint32_t rxfifo_rd_byte:32;
uint32_t reserved_8:24;
}; };
uint32_t val; uint32_t val;
} uart_fifo_reg_t; } uart_fifo_reg_t;

View File

@@ -113,7 +113,6 @@ api-reference/peripherals/ds
api-reference/peripherals/sd_pullup_requirements api-reference/peripherals/sd_pullup_requirements
api-reference/peripherals/index api-reference/peripherals/index
api-reference/peripherals/sdmmc_host api-reference/peripherals/sdmmc_host
api-reference/peripherals/uart
api-reference/kconfig api-reference/kconfig
api-reference/network api-reference/network
api-reference/network/esp_openthread api-reference/network/esp_openthread

View File

@@ -238,19 +238,9 @@ examples/peripherals/twai/twai_self_test:
temporary: true temporary: true
reason: lack of runners 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: examples/peripherals/uart/uart_echo_rs485:
enable: enable:
- if: INCLUDE_DEFAULT == 1 or IDF_TARGET == "esp32h4" - 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: examples/peripherals/usb:
disable: disable:

View File

@@ -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 # UART Echo Example

View File

@@ -6,8 +6,8 @@ menu "Echo Example Configuration"
int "UART port number" int "UART port number"
range 0 2 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 range 0 2 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3
default 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 range 0 1
default 1 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H4 default 1
help help
UART communication port number for the example. UART communication port number for the example.
See UART documentation for available port numbers. See UART documentation for available port numbers.

View File

@@ -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 # 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). 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 | | UART Interface | #define | Default pin for ESP32 | Default pins for others | External RS485 Driver Pin |
| | | | ESP32-S2(S3, C3, C2, H4) | |
| ----------------------|--------------------|-----------------------|---------------------------|---------------------------| | ----------------------|--------------------|-----------------------|---------------------------|---------------------------|
| Transmit Data (TxD) | CONFIG_MB_UART_TXD | GPIO23 | GPIO9 | DI | | Transmit Data (TxD) | CONFIG_MB_UART_TXD | GPIO23 | GPIO9 | DI |
| Receive Data (RxD) | CONFIG_MB_UART_RXD | GPIO22 | GPIO8 | RO | | Receive Data (RxD) | CONFIG_MB_UART_RXD | GPIO22 | GPIO8 | RO |

View File

@@ -6,8 +6,8 @@ menu "Echo RS485 Example Configuration"
int "UART port number" int "UART port number"
range 0 2 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3 range 0 2 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S3
default 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 range 0 1
default 1 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32H4 default 1
help help
UART communication port number for the example. UART communication port number for the example.
See UART documentation for available port numbers. See UART documentation for available port numbers.