فهرست منبع

Merge branch 'support/add_uart_fifo_threshold_set_api' into 'master'

add simplified API to set UART threshold values for RX FIFO full and TX FIFO empty

See merge request espressif/esp-idf!6749
Mahavir Jain 6 سال پیش
والد
کامیت
c86c1ecc7e

+ 28 - 0
components/driver/include/driver/uart.h

@@ -700,6 +700,34 @@ esp_err_t uart_pattern_queue_reset(uart_port_t uart_num, int queue_length);
  */
  */
 esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode);
 esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode);
 
 
+/**
+ * @brief Set uart threshold value for RX fifo full
+ * @note If application is using higher baudrate and it is observed that bytes
+ *       in hardware RX fifo are overwritten then this threshold can be reduced
+ *
+ * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
+ * @param threshold Threshold value above which RX fifo full interrupt is generated
+ *
+ * @return
+ *     - ESP_OK   Success
+ *     - ESP_ERR_INVALID_ARG Parameter error
+ *     - ESP_ERR_INVALID_STATE Driver is not installed
+ */
+esp_err_t uart_set_rx_full_threshold(uart_port_t uart_num, int threshold);
+
+/**
+ * @brief Set uart threshold values for TX fifo empty
+ *
+ * @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
+ * @param threshold Threshold value below which TX fifo empty interrupt is generated
+ *
+ * @return
+ *     - ESP_OK   Success
+ *     - ESP_ERR_INVALID_ARG Parameter error
+ *     - ESP_ERR_INVALID_STATE Driver is not installed
+ */
+esp_err_t uart_set_tx_empty_threshold(uart_port_t uart_num, int threshold);
+
 /**
 /**
  * @brief UART set threshold timeout for TOUT feature
  * @brief UART set threshold timeout for TOUT feature
  *
  *

+ 41 - 6
components/driver/uart.c

@@ -60,6 +60,12 @@ static const char* UART_TAG = "uart";
 #define UART_PATTERN_DET_QLEN_DEFAULT (10)
 #define UART_PATTERN_DET_QLEN_DEFAULT (10)
 #define UART_MIN_WAKEUP_THRESH      (SOC_UART_MIN_WAKEUP_THRESH)
 #define UART_MIN_WAKEUP_THRESH      (SOC_UART_MIN_WAKEUP_THRESH)
 
 
+#define UART_INTR_CONFIG_FLAG ((UART_INTR_RXFIFO_FULL) \
+                            | (UART_INTR_RXFIFO_TOUT) \
+                            | (UART_INTR_RXFIFO_OVF) \
+                            | (UART_INTR_BRK_DET) \
+                            | (UART_INTR_PARITY_ERR))
+
 #define UART_ENTER_CRITICAL_ISR(mux)    portENTER_CRITICAL_ISR(mux)
 #define UART_ENTER_CRITICAL_ISR(mux)    portENTER_CRITICAL_ISR(mux)
 #define UART_EXIT_CRITICAL_ISR(mux)     portEXIT_CRITICAL_ISR(mux)
 #define UART_EXIT_CRITICAL_ISR(mux)     portEXIT_CRITICAL_ISR(mux)
 #define UART_ENTER_CRITICAL(mux)    portENTER_CRITICAL(mux)
 #define UART_ENTER_CRITICAL(mux)    portENTER_CRITICAL(mux)
@@ -1330,12 +1336,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
     }
     }
 
 
     uart_intr_config_t uart_intr = {
     uart_intr_config_t uart_intr = {
-        .intr_enable_mask = UART_INTR_RXFIFO_FULL
-                            | UART_INTR_RXFIFO_TOUT
-                            | UART_INTR_PARITY_ERR
-                            | UART_INTR_RXFIFO_OVF
-                            | UART_INTR_BRK_DET
-                            | UART_INTR_PARITY_ERR,
+        .intr_enable_mask = UART_INTR_CONFIG_FLAG,
         .rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT,
         .rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT,
         .rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT,
         .rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT,
         .txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT
         .txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT
@@ -1448,6 +1449,40 @@ esp_err_t uart_set_mode(uart_port_t uart_num, uart_mode_t mode)
     return ESP_OK;
     return ESP_OK;
 }
 }
 
 
+esp_err_t uart_set_rx_full_threshold(uart_port_t uart_num, int threshold)
+{
+    UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+    UART_CHECK((threshold < UART_RXFIFO_FULL_THRHD_V) && (threshold > 0),
+        "rx fifo full threshold value error", ESP_ERR_INVALID_ARG);
+    if (p_uart_obj[uart_num] == NULL) {
+        ESP_LOGE(UART_TAG, "call uart_driver_install API first");
+        return ESP_ERR_INVALID_STATE;
+    }
+    UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
+    if (uart_hal_get_intr_ena_status(&(uart_context[uart_num].hal)) & UART_INTR_RXFIFO_FULL) {
+        uart_hal_set_rxfifo_full_thr(&(uart_context[uart_num].hal), threshold);
+    }
+    UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
+    return ESP_OK;
+}
+
+esp_err_t uart_set_tx_empty_threshold(uart_port_t uart_num, int threshold)
+{
+    UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+    UART_CHECK((threshold < UART_TXFIFO_EMPTY_THRHD_V) && (threshold > 0),
+        "tx fifo empty threshold value error", ESP_ERR_INVALID_ARG);
+    if (p_uart_obj[uart_num] == NULL) {
+        ESP_LOGE(UART_TAG, "call uart_driver_install API first");
+        return ESP_ERR_INVALID_STATE;
+    }
+    UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock));
+    if (uart_hal_get_intr_ena_status(&(uart_context[uart_num].hal)) & UART_INTR_TXFIFO_EMPTY) {
+        uart_hal_set_txfifo_empty_thr(&(uart_context[uart_num].hal), threshold);
+    }
+    UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));
+    return ESP_OK;
+}
+
 esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh)
 esp_err_t uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh)
 {
 {
     UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
     UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);

+ 12 - 0
components/soc/esp32/include/hal/uart_ll.h

@@ -139,6 +139,18 @@ static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask)
     hw->int_clr.val = mask;
     hw->int_clr.val = mask;
 }
 }
 
 
+/**
+ * @brief  Get status of enabled interrupt.
+ *
+ * @param  hw Beginning address of the peripheral registers.
+ *
+ * @return Interrupt enabled value
+ */
+static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw)
+{
+    return hw->int_ena.val;
+}
+
 /**
 /**
  * @brief  Read the UART rxfifo.
  * @brief  Read the UART rxfifo.
  *
  *

+ 12 - 0
components/soc/esp32s2beta/include/hal/uart_ll.h

@@ -137,6 +137,18 @@ static inline void uart_ll_clr_intsts_mask(uart_dev_t *hw, uint32_t mask)
     hw->int_clr.val = mask;
     hw->int_clr.val = mask;
 }
 }
 
 
+/**
+ * @brief  Get status of enabled interrupt.
+ *
+ * @param  hw Beginning address of the peripheral registers.
+ *
+ * @return interrupt enable value
+ */
+static inline uint32_t uart_ll_get_intr_ena_status(uart_dev_t *hw)
+{
+    return hw->int_ena.val;
+}
+
 /**
 /**
  * @brief  Read the UART rxfifo.
  * @brief  Read the UART rxfifo.
  *
  *

+ 9 - 0
components/soc/include/hal/uart_hal.h

@@ -76,6 +76,15 @@ typedef struct {
  */
  */
 #define uart_hal_get_intsts_mask(hal)  uart_ll_get_intsts_mask((hal)->dev)
 #define uart_hal_get_intsts_mask(hal)  uart_ll_get_intsts_mask((hal)->dev)
 
 
+/**
+ * @brief Get status of enabled interrupt
+ *
+ * @param  hal Context of the HAL layer
+ *
+ * @return UART Interrupt enabled value
+ */
+#define uart_hal_get_intr_ena_status(hal) uart_ll_get_intr_ena_status((hal)->dev)
+
 /**
 /**
  * @brief Get the UART pattern char configuration
  * @brief Get the UART pattern char configuration
  *
  *