5#include "soc/uart_periph.h"
11constexpr uint32_t UART_RX_INTR_MASK =
12 UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_OVF;
16constexpr uint32_t UART_TX_INTR_MASK = UART_INTR_TXFIFO_EMPTY;
26 auto* self =
static_cast<ESP32UART*
>(arg);
29 self->HandleUartInterrupt();
45#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3
48 constexpr int UART_INTR_FLAGS = 0;
50 constexpr int UART_INTR_FLAGS = ESP_INTR_FLAG_IRAM;
53 const esp_err_t err = esp_intr_alloc(uart_periph_signal[
uart_num_].irq, UART_INTR_FLAGS,
77 const uint32_t fifo_space = uart_hal_get_txfifo_len(&
uart_hal_);
84 const size_t chunk_size = std::min<size_t>(remaining, fifo_space);
88 [
this](
const uint8_t* src,
size_t size) ->
ErrorCode
90 uint32_t write_size = 0;
91 uart_hal_write_txfifo(&
uart_hal_, src,
static_cast<uint32_t
>(size),
93 return (write_size ==
static_cast<uint32_t
>(size)) ?
ErrorCode::OK
110 uart_hal_disable_intr_mask(&
uart_hal_, UART_INTR_TXFIFO_EMPTY);
120 if (!rx_config_gate_.TryEnterRx())
125 bool pushed_any =
false;
126 while (uart_hal_get_rxfifo_len(&
uart_hal_) > 0U)
128 const size_t fifo_len = uart_hal_get_rxfifo_len(&
uart_hal_);
137 [
this](uint8_t* buffer,
size_t chunk_size) ->
ErrorCode
139 int read_len =
static_cast<int>(chunk_size);
140 uart_hal_read_rxfifo(&
uart_hal_, buffer, &read_len);
141 return (read_len ==
static_cast<int>(chunk_size)) ?
ErrorCode::OK
175 const bool has_overflow = (uart_intr_status & UART_INTR_RXFIFO_OVF) != 0U;
176 const bool has_rx_data =
177 (uart_intr_status & (UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT)) != 0U;
179 if (!has_overflow && !has_rx_data)
188 uart_hal_clr_intsts_mask(&
uart_hal_, UART_INTR_RXFIFO_OVF);
192 uart_hal_clr_intsts_mask(&
uart_hal_, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT);
200 if ((uart_intr_status & UART_INTR_TXFIFO_EMPTY) == 0U)
207 uart_hal_clr_intsts_mask(&
uart_hal_, UART_INTR_TXFIFO_EMPTY);
216 uint32_t uart_intr_status = uart_hal_get_intsts_mask(&
uart_hal_);
218 while (uart_intr_status != 0)
220 if (uart_intr_status & UART_RX_INTR_MASK)
225 if (uart_intr_status & UART_TX_INTR_MASK)
230 uart_intr_status = uart_hal_get_intsts_mask(&
uart_hal_);
ESP32 UART backend with FIFO and optional GDMA fast paths.
void HandleUartInterrupt()
Dispatch pending UART interrupt reasons.
intr_handle_t uart_intr_handle_
Registered UART interrupt handle.
uart_hal_context_t uart_hal_
ESP-IDF UART HAL context.
void FillTxFifo(bool in_isr)
Drain active TX bytes into the UART FIFO backend.
bool tx_active_valid_
Whether the active TX metadata is valid.
void OnTxTransferDone(bool in_isr, ErrorCode result)
Finalize one TX transfer result.
void DrainRxFifo(bool in_isr)
Drain pending bytes from the hardware RX FIFO.
void HandleTxInterrupt(uint32_t uart_intr_status)
Handle TX-side UART interrupt reasons.
Flag::Plain in_tx_isr_
Reentry guard while processing TX ISR work.
void HandleRxInterrupt(uint32_t uart_intr_status)
Handle RX-side UART interrupt reasons.
bool uart_isr_installed_
UART ISR installation state.
UartDmaTxModel< ESP32UART > tx_dma_model_
One-shot DMA TX execution model.
uart_port_t uart_num_
Selected UART peripheral index.
size_t tx_active_offset_
Bytes already emitted for the active request.
size_t tx_active_length_
Active TX payload length in bytes.
ErrorCode InstallUartIsr()
Install the UART interrupt handler.
static void UartIsrEntry(void *arg)
UART ISR trampoline.
作用域标志管理器:构造时写入指定值,析构时恢复原值 / Scoped flag restorer: set on entry, restore on exit
SPSCQueue< uint8_t > * queue_data_
RX payload queue. 接收数据字节队列。
void ProcessPendingReads(bool in_isr)
Processes pending reads.
size_t EmptySize() const
获取剩余空槽数 / Get the current free-slot count
ErrorCode PopWithReader(Reader &&reader)
通过读取器回调弹出一个 payload。
ErrorCode PushWithWriter(Writer &&writer)
通过写入器回调推入一个 payload。
ReadPort * read_port_
读取端口 / Read port
WritePort * write_port_
写入端口 / Write port
SPSCQueue< uint8_t > * queue_data_
Payload queue for pending write bytes. 挂起写入字节的数据队列。
@ INIT_ERR
初始化错误 | Initialization error
@ OK
操作成功 | Operation successful