|
|
@@ -22,8 +22,10 @@
|
|
|
#include "soc/uart_periph.h"
|
|
|
#include "driver/uart.h"
|
|
|
#include "driver/gpio.h"
|
|
|
+#include "driver/rtc_io.h"
|
|
|
#include "driver/uart_select.h"
|
|
|
#include "esp_private/periph_ctrl.h"
|
|
|
+#include "esp_private/lp_periph_ctrl.h"
|
|
|
#include "esp_clk_tree.h"
|
|
|
#include "sdkconfig.h"
|
|
|
#include "esp_rom_gpio.h"
|
|
|
@@ -43,13 +45,21 @@
|
|
|
static const char *UART_TAG = "uart";
|
|
|
|
|
|
#define UART_EMPTY_THRESH_DEFAULT (10)
|
|
|
+#define LP_UART_EMPTY_THRESH_DEFAULT (2)
|
|
|
#define UART_FULL_THRESH_DEFAULT (120)
|
|
|
+#define LP_UART_FULL_THRESH_DEFAULT (10)
|
|
|
#define UART_TOUT_THRESH_DEFAULT (10)
|
|
|
#define UART_CLKDIV_FRAG_BIT_WIDTH (3)
|
|
|
#define UART_TX_IDLE_NUM_DEFAULT (0)
|
|
|
#define UART_PATTERN_DET_QLEN_DEFAULT (10)
|
|
|
#define UART_MIN_WAKEUP_THRESH (UART_LL_MIN_WAKEUP_THRESH)
|
|
|
|
|
|
+#if (SOC_UART_LP_NUM >= 1)
|
|
|
+#define UART_THRESHOLD_NUM(uart_num, field_name) ((uart_num < SOC_UART_HP_NUM) ? field_name : LP_##field_name)
|
|
|
+#else
|
|
|
+#define UART_THRESHOLD_NUM(uart_num, field_name) (field_name)
|
|
|
+#endif
|
|
|
+
|
|
|
#if SOC_UART_SUPPORT_WAKEUP_INT
|
|
|
#define UART_INTR_CONFIG_FLAG ((UART_INTR_RXFIFO_FULL) \
|
|
|
| (UART_INTR_RXFIFO_TOUT) \
|
|
|
@@ -112,7 +122,7 @@ typedef struct {
|
|
|
uint32_t rx_cur_remain; /*!< Data number that waiting to be read out in ring buffer item*/
|
|
|
uint8_t *rx_ptr; /*!< pointer to the current data in ring buffer*/
|
|
|
uint8_t *rx_head_ptr; /*!< pointer to the head of RX item*/
|
|
|
- uint8_t rx_data_buf[SOC_UART_FIFO_LEN]; /*!< Data buffer to stash FIFO data*/
|
|
|
+ uint8_t *rx_data_buf; /*!< Data buffer to stash FIFO data*/
|
|
|
uint8_t rx_stash_len; /*!< stashed data length.(When using flow control, after reading out FIFO data, if we fail to push to buffer, we can just stash them.) */
|
|
|
uint32_t rx_int_usr_mask; /*!< RX interrupt status. Valid at any time, regardless of RX buffer status. */
|
|
|
uart_pat_rb_t rx_pattern_pos;
|
|
|
@@ -160,9 +170,12 @@ static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0};
|
|
|
static uart_context_t uart_context[UART_NUM_MAX] = {
|
|
|
UART_CONTEX_INIT_DEF(UART_NUM_0),
|
|
|
UART_CONTEX_INIT_DEF(UART_NUM_1),
|
|
|
-#if UART_NUM_MAX > 2
|
|
|
+#if SOC_UART_HP_NUM > 2
|
|
|
UART_CONTEX_INIT_DEF(UART_NUM_2),
|
|
|
#endif
|
|
|
+#if (SOC_UART_LP_NUM >= 1)
|
|
|
+ UART_CONTEX_INIT_DEF(LP_UART_NUM_0),
|
|
|
+#endif
|
|
|
};
|
|
|
|
|
|
static portMUX_TYPE uart_selectlock = portMUX_INITIALIZER_UNLOCKED;
|
|
|
@@ -171,18 +184,26 @@ static void uart_module_enable(uart_port_t uart_num)
|
|
|
{
|
|
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
if (uart_context[uart_num].hw_enabled != true) {
|
|
|
- periph_module_enable(uart_periph_signal[uart_num].module);
|
|
|
- if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM) {
|
|
|
- // Workaround for ESP32C3/S3: enable core reset before enabling uart module clock to prevent uart output
|
|
|
- // garbage value.
|
|
|
+ if (uart_num < SOC_UART_HP_NUM) {
|
|
|
+ periph_module_enable(uart_periph_signal[uart_num].module);
|
|
|
+ if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM) {
|
|
|
+ // Workaround for ESP32C3/S3: enable core reset before enabling uart module clock to prevent uart output
|
|
|
+ // garbage value.
|
|
|
#if SOC_UART_REQUIRE_CORE_RESET
|
|
|
- uart_hal_set_reset_core(&(uart_context[uart_num].hal), true);
|
|
|
- periph_module_reset(uart_periph_signal[uart_num].module);
|
|
|
- uart_hal_set_reset_core(&(uart_context[uart_num].hal), false);
|
|
|
+ uart_hal_set_reset_core(&(uart_context[uart_num].hal), true);
|
|
|
+ periph_module_reset(uart_periph_signal[uart_num].module);
|
|
|
+ uart_hal_set_reset_core(&(uart_context[uart_num].hal), false);
|
|
|
#else
|
|
|
- periph_module_reset(uart_periph_signal[uart_num].module);
|
|
|
+ periph_module_reset(uart_periph_signal[uart_num].module);
|
|
|
#endif
|
|
|
+ }
|
|
|
+ }
|
|
|
+#if (SOC_UART_LP_NUM >= 1)
|
|
|
+ else {
|
|
|
+ lp_periph_module_enable(uart_periph_signal[uart_num].lp_module);
|
|
|
+ lp_periph_module_reset(uart_periph_signal[uart_num].lp_module);
|
|
|
}
|
|
|
+#endif
|
|
|
uart_context[uart_num].hw_enabled = true;
|
|
|
}
|
|
|
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
@@ -192,9 +213,14 @@ static void uart_module_disable(uart_port_t uart_num)
|
|
|
{
|
|
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
if (uart_context[uart_num].hw_enabled != false) {
|
|
|
- if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM ) {
|
|
|
+ if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) {
|
|
|
periph_module_disable(uart_periph_signal[uart_num].module);
|
|
|
}
|
|
|
+#if (SOC_UART_LP_NUM >= 1)
|
|
|
+ else if (uart_num >= SOC_UART_HP_NUM) {
|
|
|
+ lp_periph_module_disable(uart_periph_signal[uart_num].lp_module);
|
|
|
+ }
|
|
|
+#endif
|
|
|
uart_context[uart_num].hw_enabled = false;
|
|
|
}
|
|
|
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
@@ -263,11 +289,11 @@ esp_err_t uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate)
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
|
|
|
- uart_sclk_t src_clk;
|
|
|
+ soc_module_clk_t src_clk;
|
|
|
uint32_t sclk_freq;
|
|
|
|
|
|
uart_hal_get_sclk(&(uart_context[uart_num].hal), &src_clk);
|
|
|
- ESP_RETURN_ON_ERROR(uart_get_sclk_freq(src_clk, &sclk_freq), UART_TAG, "Invalid src_clk");
|
|
|
+ ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(src_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), UART_TAG, "Invalid src_clk");
|
|
|
|
|
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
uart_hal_set_baudrate(&(uart_context[uart_num].hal), baud_rate, sclk_freq);
|
|
|
@@ -279,11 +305,11 @@ esp_err_t uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate)
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
|
|
|
- uart_sclk_t src_clk;
|
|
|
+ soc_module_clk_t src_clk;
|
|
|
uint32_t sclk_freq;
|
|
|
|
|
|
uart_hal_get_sclk(&(uart_context[uart_num].hal), &src_clk);
|
|
|
- ESP_RETURN_ON_ERROR(uart_get_sclk_freq(src_clk, &sclk_freq), UART_TAG, "Invalid src_clk");
|
|
|
+ ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(src_clk, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), UART_TAG, "Invalid src_clk");
|
|
|
|
|
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
uart_hal_get_baudrate(&(uart_context[uart_num].hal), baudrate, sclk_freq);
|
|
|
@@ -303,8 +329,8 @@ esp_err_t uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask)
|
|
|
esp_err_t uart_set_sw_flow_ctrl(uart_port_t uart_num, bool enable, uint8_t rx_thresh_xon, uint8_t rx_thresh_xoff)
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
- ESP_RETURN_ON_FALSE((rx_thresh_xon < SOC_UART_FIFO_LEN), ESP_FAIL, UART_TAG, "rx flow xon thresh error");
|
|
|
- ESP_RETURN_ON_FALSE((rx_thresh_xoff < SOC_UART_FIFO_LEN), ESP_FAIL, UART_TAG, "rx flow xoff thresh error");
|
|
|
+ ESP_RETURN_ON_FALSE((rx_thresh_xon < UART_HW_FIFO_LEN(uart_num)), ESP_FAIL, UART_TAG, "rx flow xon thresh error");
|
|
|
+ ESP_RETURN_ON_FALSE((rx_thresh_xoff < UART_HW_FIFO_LEN(uart_num)), ESP_FAIL, UART_TAG, "rx flow xoff thresh error");
|
|
|
uart_sw_flowctrl_t sw_flow_ctl = {
|
|
|
.xon_char = XON,
|
|
|
.xoff_char = XOFF,
|
|
|
@@ -320,7 +346,7 @@ esp_err_t uart_set_sw_flow_ctrl(uart_port_t uart_num, bool enable, uint8_t rx_t
|
|
|
esp_err_t uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh)
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
- ESP_RETURN_ON_FALSE((rx_thresh < SOC_UART_FIFO_LEN), ESP_FAIL, UART_TAG, "rx flow thresh error");
|
|
|
+ ESP_RETURN_ON_FALSE((rx_thresh < UART_HW_FIFO_LEN(uart_num)), ESP_FAIL, UART_TAG, "rx flow thresh error");
|
|
|
ESP_RETURN_ON_FALSE((flow_ctrl < UART_HW_FLOWCTRL_MAX), ESP_FAIL, UART_TAG, "hw_flowctrl mode error");
|
|
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
uart_hal_set_hw_flow_ctrl(&(uart_context[uart_num].hal), flow_ctrl, rx_thresh);
|
|
|
@@ -515,9 +541,9 @@ esp_err_t uart_pattern_queue_reset(uart_port_t uart_num, int queue_length)
|
|
|
esp_err_t uart_enable_pattern_det_baud_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle)
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE(uart_num < UART_NUM_MAX, ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
- ESP_RETURN_ON_FALSE(chr_tout >= 0 && chr_tout <= UART_RX_GAP_TOUT_V, ESP_FAIL, UART_TAG, "uart pattern set error\n");
|
|
|
- ESP_RETURN_ON_FALSE(post_idle >= 0 && post_idle <= UART_POST_IDLE_NUM_V, ESP_FAIL, UART_TAG, "uart pattern set error\n");
|
|
|
- ESP_RETURN_ON_FALSE(pre_idle >= 0 && pre_idle <= UART_PRE_IDLE_NUM_V, ESP_FAIL, UART_TAG, "uart pattern set error\n");
|
|
|
+ ESP_RETURN_ON_FALSE(chr_tout >= 0 && chr_tout <= UART_THRESHOLD_NUM(uart_num, UART_RX_GAP_TOUT_V), ESP_FAIL, UART_TAG, "uart pattern set error\n");
|
|
|
+ ESP_RETURN_ON_FALSE(post_idle >= 0 && post_idle <= UART_THRESHOLD_NUM(uart_num, UART_POST_IDLE_NUM_V), ESP_FAIL, UART_TAG, "uart pattern set error\n");
|
|
|
+ ESP_RETURN_ON_FALSE(pre_idle >= 0 && pre_idle <= UART_THRESHOLD_NUM(uart_num, UART_PRE_IDLE_NUM_V), ESP_FAIL, UART_TAG, "uart pattern set error\n");
|
|
|
uart_at_cmd_t at_cmd = {0};
|
|
|
at_cmd.cmd_char = pattern_chr;
|
|
|
at_cmd.char_num = chr_num;
|
|
|
@@ -570,7 +596,7 @@ esp_err_t uart_disable_tx_intr(uart_port_t uart_num)
|
|
|
esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh)
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
- ESP_RETURN_ON_FALSE((thresh < SOC_UART_FIFO_LEN), ESP_FAIL, UART_TAG, "empty intr threshold error");
|
|
|
+ ESP_RETURN_ON_FALSE((thresh < UART_HW_FIFO_LEN(uart_num)), ESP_FAIL, UART_TAG, "empty intr threshold error");
|
|
|
uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_INTR_TXFIFO_EMPTY);
|
|
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
uart_hal_set_txfifo_empty_thr(&(uart_context[uart_num].hal), thresh);
|
|
|
@@ -592,13 +618,26 @@ static bool uart_try_set_iomux_pin(uart_port_t uart_num, int io_num, uint32_t id
|
|
|
|
|
|
/* Assign the correct funct to the GPIO. */
|
|
|
assert (upin->iomux_func != -1);
|
|
|
- gpio_iomux_out(io_num, upin->iomux_func, false);
|
|
|
+ if (uart_num < SOC_UART_HP_NUM) {
|
|
|
+ gpio_iomux_out(io_num, upin->iomux_func, false);
|
|
|
|
|
|
- /* If the pin is input, we also have to redirect the signal,
|
|
|
- * in order to bypasse the GPIO matrix. */
|
|
|
- if (upin->input) {
|
|
|
- gpio_iomux_in(io_num, upin->signal);
|
|
|
+ /* If the pin is input, we also have to redirect the signal,
|
|
|
+ * in order to bypasse the GPIO matrix. */
|
|
|
+ if (upin->input) {
|
|
|
+ gpio_iomux_in(io_num, upin->signal);
|
|
|
+ }
|
|
|
}
|
|
|
+#if (SOC_UART_LP_NUM >= 1)
|
|
|
+ else {
|
|
|
+ if (upin->input) {
|
|
|
+ rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_INPUT_ONLY);
|
|
|
+ } else {
|
|
|
+ rtc_gpio_set_direction(io_num, RTC_GPIO_MODE_OUTPUT_ONLY);
|
|
|
+ }
|
|
|
+ rtc_gpio_init(io_num);
|
|
|
+ rtc_gpio_iomux_func_sel(io_num, upin->iomux_func);
|
|
|
+ }
|
|
|
+#endif
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
@@ -609,10 +648,21 @@ esp_err_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int r
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num >= 0), ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
- ESP_RETURN_ON_FALSE((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), ESP_FAIL, UART_TAG, "tx_io_num error");
|
|
|
- ESP_RETURN_ON_FALSE((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), ESP_FAIL, UART_TAG, "rx_io_num error");
|
|
|
- ESP_RETURN_ON_FALSE((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), ESP_FAIL, UART_TAG, "rts_io_num error");
|
|
|
- ESP_RETURN_ON_FALSE((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), ESP_FAIL, UART_TAG, "cts_io_num error");
|
|
|
+ if (uart_num < SOC_UART_HP_NUM) {
|
|
|
+ ESP_RETURN_ON_FALSE((tx_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(tx_io_num))), ESP_FAIL, UART_TAG, "tx_io_num error");
|
|
|
+ ESP_RETURN_ON_FALSE((rx_io_num < 0 || (GPIO_IS_VALID_GPIO(rx_io_num))), ESP_FAIL, UART_TAG, "rx_io_num error");
|
|
|
+ ESP_RETURN_ON_FALSE((rts_io_num < 0 || (GPIO_IS_VALID_OUTPUT_GPIO(rts_io_num))), ESP_FAIL, UART_TAG, "rts_io_num error");
|
|
|
+ ESP_RETURN_ON_FALSE((cts_io_num < 0 || (GPIO_IS_VALID_GPIO(cts_io_num))), ESP_FAIL, UART_TAG, "cts_io_num error");
|
|
|
+ }
|
|
|
+#if (SOC_UART_LP_NUM >= 1)
|
|
|
+ else { // LP_UART has its fixed IOs
|
|
|
+ const uart_periph_sig_t *pins = uart_periph_signal[uart_num].pins;
|
|
|
+ ESP_RETURN_ON_FALSE((tx_io_num < 0 || (tx_io_num == pins[SOC_UART_TX_PIN_IDX].default_gpio)), ESP_FAIL, UART_TAG, "tx_io_num error");
|
|
|
+ ESP_RETURN_ON_FALSE((rx_io_num < 0 || (rx_io_num == pins[SOC_UART_RX_PIN_IDX].default_gpio)), ESP_FAIL, UART_TAG, "rx_io_num error");
|
|
|
+ ESP_RETURN_ON_FALSE((rts_io_num < 0 || (rts_io_num == pins[SOC_UART_RTS_PIN_IDX].default_gpio)), ESP_FAIL, UART_TAG, "rts_io_num error");
|
|
|
+ ESP_RETURN_ON_FALSE((cts_io_num < 0 || (cts_io_num == pins[SOC_UART_CTS_PIN_IDX].default_gpio)), ESP_FAIL, UART_TAG, "cts_io_num error");
|
|
|
+ }
|
|
|
+#endif
|
|
|
|
|
|
/* In the following statements, if the io_num is negative, no need to configure anything. */
|
|
|
if (tx_io_num >= 0 && !uart_try_set_iomux_pin(uart_num, tx_io_num, SOC_UART_TX_PIN_IDX)) {
|
|
|
@@ -666,7 +716,7 @@ esp_err_t uart_set_dtr(uart_port_t uart_num, int level)
|
|
|
esp_err_t uart_set_tx_idle_num(uart_port_t uart_num, uint16_t idle_num)
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
- ESP_RETURN_ON_FALSE((idle_num <= UART_TX_IDLE_NUM_V), ESP_FAIL, UART_TAG, "uart idle num error");
|
|
|
+ ESP_RETURN_ON_FALSE((idle_num <= UART_THRESHOLD_NUM(uart_num, UART_TX_IDLE_NUM_V)), ESP_FAIL, UART_TAG, "uart idle num error");
|
|
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
uart_hal_set_tx_idle_num(&(uart_context[uart_num].hal), idle_num);
|
|
|
UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
@@ -677,22 +727,40 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
ESP_RETURN_ON_FALSE((uart_config), ESP_FAIL, UART_TAG, "param null");
|
|
|
- ESP_RETURN_ON_FALSE((uart_config->rx_flow_ctrl_thresh < SOC_UART_FIFO_LEN), ESP_FAIL, UART_TAG, "rx flow thresh error");
|
|
|
+ ESP_RETURN_ON_FALSE((uart_config->rx_flow_ctrl_thresh < UART_HW_FIFO_LEN(uart_num)), ESP_FAIL, UART_TAG, "rx flow thresh error");
|
|
|
ESP_RETURN_ON_FALSE((uart_config->flow_ctrl < UART_HW_FLOWCTRL_MAX), ESP_FAIL, UART_TAG, "hw_flowctrl mode error");
|
|
|
ESP_RETURN_ON_FALSE((uart_config->data_bits < UART_DATA_BITS_MAX), ESP_FAIL, UART_TAG, "data bit error");
|
|
|
+
|
|
|
uart_module_enable(uart_num);
|
|
|
- uart_sclk_t clk_src = (uart_config->source_clk) ? uart_config->source_clk : UART_SCLK_DEFAULT; // if no specifying the clock source (soc_module_clk_t starts from 1), then just use the default clock
|
|
|
+
|
|
|
+ soc_module_clk_t uart_sclk_sel = 0; // initialize to an invalid module clock ID
|
|
|
+ if (uart_num < SOC_UART_HP_NUM) {
|
|
|
+ uart_sclk_sel = (soc_module_clk_t)((uart_config->source_clk) ? uart_config->source_clk : UART_SCLK_DEFAULT); // if no specifying the clock source (soc_module_clk_t starts from 1), then just use the default clock
|
|
|
+ }
|
|
|
+#if (SOC_UART_LP_NUM >= 1)
|
|
|
+ else {
|
|
|
+ uart_sclk_sel = (soc_module_clk_t)((uart_config->lp_source_clk) ? uart_config->lp_source_clk : LP_UART_SCLK_DEFAULT);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
#if SOC_UART_SUPPORT_RTC_CLK
|
|
|
- if (clk_src == UART_SCLK_RTC) {
|
|
|
+ if (uart_sclk_sel == (soc_module_clk_t)UART_SCLK_RTC) {
|
|
|
periph_rtc_dig_clk8m_enable();
|
|
|
}
|
|
|
#endif
|
|
|
uint32_t sclk_freq;
|
|
|
- ESP_RETURN_ON_ERROR(uart_get_sclk_freq(clk_src, &sclk_freq), UART_TAG, "Invalid src_clk");
|
|
|
+ ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz(uart_sclk_sel, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sclk_freq), UART_TAG, "Invalid src_clk");
|
|
|
|
|
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
uart_hal_init(&(uart_context[uart_num].hal), uart_num);
|
|
|
- uart_hal_set_sclk(&(uart_context[uart_num].hal), clk_src);
|
|
|
+ if (uart_num < SOC_UART_HP_NUM) {
|
|
|
+ uart_hal_set_sclk(&(uart_context[uart_num].hal), uart_sclk_sel);
|
|
|
+ }
|
|
|
+#if (SOC_UART_LP_NUM >= 1)
|
|
|
+ else {
|
|
|
+ lp_periph_set_clk_src(uart_periph_signal[uart_num].lp_module, uart_sclk_sel);
|
|
|
+ }
|
|
|
+#endif
|
|
|
uart_hal_set_baudrate(&(uart_context[uart_num].hal), uart_config->baud_rate, sclk_freq);
|
|
|
uart_hal_set_parity(&(uart_context[uart_num].hal), uart_config->parity);
|
|
|
uart_hal_set_data_bit_num(&(uart_context[uart_num].hal), uart_config->data_bits);
|
|
|
@@ -1174,7 +1242,7 @@ static int uart_tx_all(uart_port_t uart_num, const char *src, size_t size, bool
|
|
|
xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void *) (src + offset), send_size, portMAX_DELAY);
|
|
|
size -= send_size;
|
|
|
offset += send_size;
|
|
|
- uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT);
|
|
|
+ uart_enable_tx_intr(uart_num, 1, UART_THRESHOLD_NUM(uart_num, UART_EMPTY_THRESH_DEFAULT));
|
|
|
}
|
|
|
} else {
|
|
|
while (size) {
|
|
|
@@ -1183,7 +1251,7 @@ static int uart_tx_all(uart_port_t uart_num, const char *src, size_t size, bool
|
|
|
uint32_t sent = uart_enable_tx_write_fifo(uart_num, (const uint8_t *) src, size);
|
|
|
if (sent < size) {
|
|
|
p_uart_obj[uart_num]->tx_waiting_fifo = true;
|
|
|
- uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT);
|
|
|
+ uart_enable_tx_intr(uart_num, 1, UART_THRESHOLD_NUM(uart_num, UART_EMPTY_THRESH_DEFAULT));
|
|
|
}
|
|
|
size -= sent;
|
|
|
src += sent;
|
|
|
@@ -1425,15 +1493,20 @@ static void uart_free_driver_obj(uart_obj_t *uart_obj)
|
|
|
free(uart_obj->tx_done_sem_struct);
|
|
|
free(uart_obj->tx_fifo_sem_struct);
|
|
|
#endif
|
|
|
+ free(uart_obj->rx_data_buf);
|
|
|
free(uart_obj);
|
|
|
}
|
|
|
|
|
|
-static uart_obj_t *uart_alloc_driver_obj(int event_queue_size, int tx_buffer_size, int rx_buffer_size)
|
|
|
+static uart_obj_t *uart_alloc_driver_obj(uart_port_t uart_num, int event_queue_size, int tx_buffer_size, int rx_buffer_size)
|
|
|
{
|
|
|
uart_obj_t *uart_obj = heap_caps_calloc(1, sizeof(uart_obj_t), UART_MALLOC_CAPS);
|
|
|
if (!uart_obj) {
|
|
|
return NULL;
|
|
|
}
|
|
|
+ uart_obj->rx_data_buf = heap_caps_calloc(UART_HW_FIFO_LEN(uart_num), sizeof(uint32_t), UART_MALLOC_CAPS);
|
|
|
+ if (!uart_obj->rx_data_buf) {
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
#if CONFIG_UART_ISR_IN_IRAM
|
|
|
if (event_queue_size > 0) {
|
|
|
uart_obj->event_queue_storage = heap_caps_calloc(event_queue_size, sizeof(uart_event_t), UART_MALLOC_CAPS);
|
|
|
@@ -1524,8 +1597,8 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
|
|
ESP_RETURN_ON_FALSE((uart_num != CONFIG_ESP_CONSOLE_UART_NUM), ESP_FAIL, UART_TAG, "UART used by GDB-stubs! Please disable GDB in menuconfig.");
|
|
|
#endif // CONFIG_ESP_SYSTEM_GDBSTUB_RUNTIME
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_FAIL, UART_TAG, "uart_num error");
|
|
|
- ESP_RETURN_ON_FALSE((rx_buffer_size > SOC_UART_FIFO_LEN), ESP_FAIL, UART_TAG, "uart rx buffer length error");
|
|
|
- ESP_RETURN_ON_FALSE((tx_buffer_size > SOC_UART_FIFO_LEN) || (tx_buffer_size == 0), ESP_FAIL, UART_TAG, "uart tx buffer length error");
|
|
|
+ ESP_RETURN_ON_FALSE((rx_buffer_size > UART_HW_FIFO_LEN(uart_num)), ESP_FAIL, UART_TAG, "uart rx buffer length error");
|
|
|
+ ESP_RETURN_ON_FALSE((tx_buffer_size > UART_HW_FIFO_LEN(uart_num)) || (tx_buffer_size == 0), ESP_FAIL, UART_TAG, "uart tx buffer length error");
|
|
|
#if CONFIG_UART_ISR_IN_IRAM
|
|
|
if ((intr_alloc_flags & ESP_INTR_FLAG_IRAM) == 0) {
|
|
|
ESP_LOGI(UART_TAG, "ESP_INTR_FLAG_IRAM flag not set while CONFIG_UART_ISR_IN_IRAM is enabled, flag updated");
|
|
|
@@ -1539,7 +1612,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
|
|
#endif
|
|
|
|
|
|
if (p_uart_obj[uart_num] == NULL) {
|
|
|
- p_uart_obj[uart_num] = uart_alloc_driver_obj(event_queue_size, tx_buffer_size, rx_buffer_size);
|
|
|
+ p_uart_obj[uart_num] = uart_alloc_driver_obj(uart_num, event_queue_size, tx_buffer_size, rx_buffer_size);
|
|
|
if (p_uart_obj[uart_num] == NULL) {
|
|
|
ESP_LOGE(UART_TAG, "UART driver malloc error");
|
|
|
return ESP_FAIL;
|
|
|
@@ -1577,9 +1650,9 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
|
|
|
|
|
uart_intr_config_t uart_intr = {
|
|
|
.intr_enable_mask = UART_INTR_CONFIG_FLAG,
|
|
|
- .rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT,
|
|
|
+ .rxfifo_full_thresh = UART_THRESHOLD_NUM(uart_num, UART_FULL_THRESH_DEFAULT),
|
|
|
.rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT,
|
|
|
- .txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT,
|
|
|
+ .txfifo_empty_intr_thresh = UART_THRESHOLD_NUM(uart_num, UART_EMPTY_THRESH_DEFAULT),
|
|
|
};
|
|
|
uart_module_enable(uart_num);
|
|
|
uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), UART_LL_INTR_MASK);
|
|
|
@@ -1616,9 +1689,9 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
|
|
|
p_uart_obj[uart_num] = NULL;
|
|
|
|
|
|
#if SOC_UART_SUPPORT_RTC_CLK
|
|
|
- uart_sclk_t sclk = 0;
|
|
|
+ soc_module_clk_t sclk = 0;
|
|
|
uart_hal_get_sclk(&(uart_context[uart_num].hal), &sclk);
|
|
|
- if (sclk == UART_SCLK_RTC) {
|
|
|
+ if (sclk == (soc_module_clk_t)UART_SCLK_RTC) {
|
|
|
periph_rtc_dig_clk8m_disable();
|
|
|
}
|
|
|
#endif
|
|
|
@@ -1653,6 +1726,9 @@ esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode)
|
|
|
ESP_RETURN_ON_FALSE((!uart_hal_is_hw_rts_en(&(uart_context[uart_num].hal))), ESP_ERR_INVALID_ARG, UART_TAG,
|
|
|
"disable hw flowctrl before using RS485 mode");
|
|
|
}
|
|
|
+ if (uart_num >= SOC_UART_HP_NUM) {
|
|
|
+ ESP_RETURN_ON_FALSE((mode == UART_MODE_UART), ESP_ERR_INVALID_ARG, UART_TAG, "LP_UART can only be in normal UART mode");
|
|
|
+ }
|
|
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
uart_hal_set_mode(&(uart_context[uart_num].hal), mode);
|
|
|
if (mode == UART_MODE_RS485_COLLISION_DETECT) {
|
|
|
@@ -1673,7 +1749,7 @@ esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode)
|
|
|
esp_err_t uart_set_rx_full_threshold(uart_port_t uart_num, int threshold)
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_ERR_INVALID_ARG, UART_TAG, "uart_num error");
|
|
|
- ESP_RETURN_ON_FALSE((threshold < UART_RXFIFO_FULL_THRHD_V) && (threshold > 0), ESP_ERR_INVALID_ARG, UART_TAG,
|
|
|
+ ESP_RETURN_ON_FALSE((threshold < UART_THRESHOLD_NUM(uart_num, UART_RXFIFO_FULL_THRHD_V)) && (threshold > 0), ESP_ERR_INVALID_ARG, UART_TAG,
|
|
|
"rx fifo full threshold value error");
|
|
|
if (p_uart_obj[uart_num] == NULL) {
|
|
|
ESP_LOGE(UART_TAG, "call uart_driver_install API first");
|
|
|
@@ -1690,7 +1766,7 @@ esp_err_t uart_set_rx_full_threshold(uart_port_t uart_num, int threshold)
|
|
|
esp_err_t uart_set_tx_empty_threshold(uart_port_t uart_num, int threshold)
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_ERR_INVALID_ARG, UART_TAG, "uart_num error");
|
|
|
- ESP_RETURN_ON_FALSE((threshold < UART_TXFIFO_EMPTY_THRHD_V) && (threshold > 0), ESP_ERR_INVALID_ARG, UART_TAG,
|
|
|
+ ESP_RETURN_ON_FALSE((threshold < UART_THRESHOLD_NUM(uart_num, UART_TXFIFO_EMPTY_THRHD_V)) && (threshold > 0), ESP_ERR_INVALID_ARG, UART_TAG,
|
|
|
"tx fifo empty threshold value error");
|
|
|
if (p_uart_obj[uart_num] == NULL) {
|
|
|
ESP_LOGE(UART_TAG, "call uart_driver_install API first");
|
|
|
@@ -1733,7 +1809,7 @@ esp_err_t uart_get_collision_flag(uart_port_t uart_num, bool *collision_flag)
|
|
|
esp_err_t uart_set_wakeup_threshold(uart_port_t uart_num, int wakeup_threshold)
|
|
|
{
|
|
|
ESP_RETURN_ON_FALSE((uart_num < UART_NUM_MAX), ESP_ERR_INVALID_ARG, UART_TAG, "uart_num error");
|
|
|
- ESP_RETURN_ON_FALSE((wakeup_threshold <= UART_ACTIVE_THRESHOLD_V && wakeup_threshold > UART_MIN_WAKEUP_THRESH), ESP_ERR_INVALID_ARG, UART_TAG,
|
|
|
+ ESP_RETURN_ON_FALSE((wakeup_threshold <= UART_THRESHOLD_NUM(uart_num, UART_ACTIVE_THRESHOLD_V) && wakeup_threshold > UART_MIN_WAKEUP_THRESH), ESP_ERR_INVALID_ARG, UART_TAG,
|
|
|
"wakeup_threshold out of bounds");
|
|
|
UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
|
|
|
uart_hal_set_wakeup_thrd(&(uart_context[uart_num].hal), wakeup_threshold);
|