From eec821223733bcd263769f977de2e632634408bc Mon Sep 17 00:00:00 2001 From: kewal shah Date: Mon, 18 Nov 2019 19:06:40 +0530 Subject: [PATCH] add simplified API to set UART threshold values for RX FIFO full and TX FIFO empty --- components/driver/include/driver/uart.h | 28 +++++++++++ components/driver/uart.c | 47 ++++++++++++++++--- components/soc/esp32/include/hal/uart_ll.h | 12 +++++ .../soc/esp32s2beta/include/hal/uart_ll.h | 12 +++++ components/soc/include/hal/uart_hal.h | 9 ++++ 5 files changed, 102 insertions(+), 6 deletions(-) diff --git a/components/driver/include/driver/uart.h b/components/driver/include/driver/uart.h index 764b03a6e7..57f4f79045 100644 --- a/components/driver/include/driver/uart.h +++ b/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); +/** + * @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 * diff --git a/components/driver/uart.c b/components/driver/uart.c index 4b1fde6879..9750ac486f 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -60,6 +60,12 @@ static const char* UART_TAG = "uart"; #define UART_PATTERN_DET_QLEN_DEFAULT (10) #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_EXIT_CRITICAL_ISR(mux) portEXIT_CRITICAL_ISR(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 = { - .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, .rx_timeout_thresh = UART_TOUT_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; } +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) { UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG); diff --git a/components/soc/esp32/include/hal/uart_ll.h b/components/soc/esp32/include/hal/uart_ll.h index 54d30568c1..def1ad062b 100644 --- a/components/soc/esp32/include/hal/uart_ll.h +++ b/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; } +/** + * @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. * diff --git a/components/soc/esp32s2beta/include/hal/uart_ll.h b/components/soc/esp32s2beta/include/hal/uart_ll.h index 3562fd7787..7a2a045d35 100644 --- a/components/soc/esp32s2beta/include/hal/uart_ll.h +++ b/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; } +/** + * @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. * diff --git a/components/soc/include/hal/uart_hal.h b/components/soc/include/hal/uart_hal.h index 1c9d65d5b6..1547d61bf8 100644 --- a/components/soc/include/hal/uart_hal.h +++ b/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) +/** + * @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 *