mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'fix/lp_uart_data_bits_v5.5' into 'release/v5.5'
fix(ulp/lp_core): fix LP UART data_bits validation and add full word-length test coverage (v5.5) See merge request espressif/esp-idf!48032
This commit is contained in:
@@ -194,45 +194,45 @@ int lp_core_uart_read_bytes(uart_port_t lp_uart_num, void *buf, size_t size, int
|
||||
uint32_t to = 0;
|
||||
|
||||
while (remaining_bytes > 0) {
|
||||
/* Read from the Rx FIFO
|
||||
* We set rx_len to -1 to read all bytes in the Rx FIFO
|
||||
*/
|
||||
rx_len = -1;
|
||||
uart_hal_read_rxfifo(&hal, (uint8_t *)(buf + bytes_rcvd), &rx_len);
|
||||
/* Drain only as many bytes as fit in the remaining buffer space */
|
||||
int fifo_len = uart_ll_get_rxfifo_len(hal.dev);
|
||||
rx_len = (fifo_len < remaining_bytes) ? fifo_len : remaining_bytes;
|
||||
|
||||
if (rx_len) {
|
||||
/* We have some data to read from the Rx FIFO. Check Rx interrupt status */
|
||||
intr_status = uart_hal_get_intraw_mask(&hal);
|
||||
if ((intr_status & UART_INTR_RXFIFO_FULL) ||
|
||||
(intr_status & UART_INTR_RXFIFO_TOUT)) {
|
||||
/* This is expected. Clear interrupt status and break */
|
||||
uart_hal_clr_intsts_mask(&hal, intr_mask);
|
||||
if (rx_len > 0) {
|
||||
uart_hal_read_rxfifo(&hal, (uint8_t *)(buf + bytes_rcvd), &rx_len);
|
||||
bytes_rcvd += rx_len;
|
||||
remaining_bytes -= rx_len;
|
||||
|
||||
/* RXFIFO_FULL / RXFIFO_TOUT raw bits are sticky; acknowledge them
|
||||
* so they do not short-circuit the next iteration. */
|
||||
uart_hal_clr_intsts_mask(&hal, LP_UART_RX_INT_FLAG);
|
||||
|
||||
if (remaining_bytes <= 0) {
|
||||
break;
|
||||
} else if ((intr_status & UART_INTR_RXFIFO_OVF)) {
|
||||
/* We reset the Rx FIFO if it overflows */
|
||||
}
|
||||
|
||||
/* FIFO overflow and parity/framing errors are terminal */
|
||||
intr_status = uart_hal_get_intraw_mask(&hal);
|
||||
if (intr_status & UART_INTR_RXFIFO_OVF) {
|
||||
uart_hal_clr_intsts_mask(&hal, intr_mask);
|
||||
uart_hal_rxfifo_rst(&hal);
|
||||
break;
|
||||
} else if ((intr_status & LP_UART_ERR_INT_FLAG)) {
|
||||
/* Transaction error. Abort */
|
||||
} else if (intr_status & LP_UART_ERR_INT_FLAG) {
|
||||
uart_hal_clr_intsts_mask(&hal, intr_mask);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Update the byte counters */
|
||||
bytes_rcvd += rx_len;
|
||||
remaining_bytes -= rx_len;
|
||||
} else {
|
||||
/* We have no data to read from the Rx FIFO. Check for transaction timeout */
|
||||
/* FIFO empty. Honour the caller's timeout. */
|
||||
ret = lp_core_uart_check_timeout(intr_mask, timeout, &to);
|
||||
if (ret == ESP_ERR_TIMEOUT) {
|
||||
/* Timeout. Clear interrupt status and break */
|
||||
uart_hal_clr_intsts_mask(&hal, intr_mask);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the number of bytes received */
|
||||
return bytes_rcvd;
|
||||
if (bytes_rcvd > size) {
|
||||
bytes_rcvd = size;
|
||||
}
|
||||
return (int)bytes_rcvd;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -34,9 +34,9 @@ static esp_err_t lp_core_uart_param_config(const lp_core_uart_cfg_t *cfg)
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
/* Argument sanity check */
|
||||
if ((cfg->uart_proto_cfg.rx_flow_ctrl_thresh > SOC_LP_UART_FIFO_LEN) ||
|
||||
(cfg->uart_proto_cfg.flow_ctrl > UART_HW_FLOWCTRL_MAX) ||
|
||||
(cfg->uart_proto_cfg.data_bits > UART_DATA_BITS_MAX)) {
|
||||
if ((cfg->uart_proto_cfg.rx_flow_ctrl_thresh >= SOC_LP_UART_FIFO_LEN) ||
|
||||
(cfg->uart_proto_cfg.flow_ctrl >= UART_HW_FLOWCTRL_MAX) ||
|
||||
(cfg->uart_proto_cfg.data_bits >= UART_DATA_BITS_MAX)) {
|
||||
// Invalid config
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
@@ -154,10 +154,13 @@ static esp_err_t lp_core_uart_set_pin(const lp_core_uart_cfg_t *cfg)
|
||||
ret = lp_uart_config_io(cfg->uart_pin_cfg.tx_io_num, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_TX_PIN_IDX);
|
||||
/* Configure Rx Pin */
|
||||
ret = lp_uart_config_io(cfg->uart_pin_cfg.rx_io_num, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_RX_PIN_IDX);
|
||||
/* Configure RTS Pin */
|
||||
ret = lp_uart_config_io(cfg->uart_pin_cfg.rts_io_num, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_RTS_PIN_IDX);
|
||||
/* Configure CTS Pin */
|
||||
ret = lp_uart_config_io(cfg->uart_pin_cfg.cts_io_num, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_CTS_PIN_IDX);
|
||||
/* Configure RTS/CTS only when hardware flow control is enabled */
|
||||
if (cfg->uart_proto_cfg.flow_ctrl & UART_HW_FLOWCTRL_RTS) {
|
||||
ret = lp_uart_config_io(cfg->uart_pin_cfg.rts_io_num, RTC_GPIO_MODE_OUTPUT_ONLY, SOC_UART_RTS_PIN_IDX);
|
||||
}
|
||||
if (cfg->uart_proto_cfg.flow_ctrl & UART_HW_FLOWCTRL_CTS) {
|
||||
ret = lp_uart_config_io(cfg->uart_pin_cfg.cts_io_num, RTC_GPIO_MODE_INPUT_ONLY, SOC_UART_CTS_PIN_IDX);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user