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;
17constexpr uint32_t UART_TX_IDLE_INTR_MASK = UART_INTR_TX_DONE;
25void IRAM_ATTR ESP32UART::UartIsrEntry(
void* arg)
27 auto* self =
static_cast<ESP32UART*
>(arg);
30 self->HandleUartInterrupt();
36 if (uart_isr_installed_)
43 constexpr int UART_INTR_FLAGS = 0;
45 const esp_err_t err = esp_intr_alloc(uart_periph_signal[uart_num_].irq, UART_INTR_FLAGS,
46 UartIsrEntry,
this, &uart_intr_handle_);
52 uart_isr_installed_ =
true;
60void IRAM_ATTR ESP32UART::FillTxFifo(
bool in_isr)
62 const uint32_t fifo_space = uart_hal_get_txfifo_len(&uart_hal_);
65 if (_write_port.
Size() != 0U)
67 EnableUartInterrupt(UART_INTR_TXFIFO_EMPTY);
77 DisableUartInterrupt(UART_INTR_TXFIFO_EMPTY);
82 std::min<size_t>(fifo_space, queue.AvailableSize()),
83 [
this](
const uint8_t* first,
size_t first_size,
const uint8_t* second,
84 size_t second_size) ->
size_t
89 uint32_t first_written = 0U;
90 uart_hal_write_txfifo(&uart_hal_, first, static_cast<uint32_t>(first_size),
92 written = std::min<size_t>(first_written, first_size);
93 if (written != first_size)
98 if (second_size != 0U)
100 uint32_t second_written = 0U;
101 uart_hal_write_txfifo(&uart_hal_, second,
static_cast<uint32_t
>(second_size),
103 written += std::min<size_t>(second_written, second_size);
109 if (accepted == 0U || _write_port.Size() != 0U)
111 EnableUartInterrupt(UART_INTR_TXFIFO_EMPTY);
115 DisableUartInterrupt(UART_INTR_TXFIFO_EMPTY);
123void IRAM_ATTR ESP32UART::DrainRxFifo(
bool in_isr)
125 auto queue = _read_port.GetReadQueue(in_isr);
126 while (uart_hal_get_rxfifo_len(&uart_hal_) > 0U)
128 const size_t free_space = queue.EmptySize();
129 if (free_space == 0U)
135 std::min({free_space, rx_isr_buffer_size_,
136 static_cast<size_t>(uart_hal_get_rxfifo_len(&uart_hal_))});
137 DEV_ASSERT_FROM_CALLBACK(chunk != 0U, in_isr);
138 int read_size =
static_cast<int>(chunk);
139 uart_hal_read_rxfifo(&uart_hal_, rx_isr_buffer_, &read_size);
140 DEV_ASSERT_FROM_CALLBACK(read_size > 0 &&
static_cast<size_t>(read_size) <= chunk,
142 [[maybe_unused]]
const auto push_batch_result =
143 queue.PushBatch(rx_isr_buffer_,
static_cast<size_t>(read_size));
144 DEV_ASSERT_FROM_CALLBACK(push_batch_result == ErrorCode::OK, in_isr);
148 if (queue.EmptySize() == 0U)
150 DisableUartInterrupt(UART_RX_INTR_MASK);
154 EnableUartInterrupt(UART_RX_INTR_MASK);
162void IRAM_ATTR ESP32UART::HandleUartInterrupt()
164 const uint32_t handled_mask =
165 UART_RX_INTR_MASK | UART_TX_INTR_MASK | UART_TX_IDLE_INTR_MASK;
166 uint32_t handled = CaptureUartInterrupt(handled_mask);
167 while (handled != 0U)
169 uint32_t events = 0U;
170 if ((handled & UART_RX_INTR_MASK) != 0U)
172 events |= EVENT_RX_WORK;
174 if ((handled & (UART_TX_INTR_MASK | UART_TX_IDLE_INTR_MASK)) != 0U)
176 events |= EVENT_TX_WORK;
178 service_.Invoke(events,
true, [
this](uint32_t owner_events,
bool owner_isr)
179 { ServiceEvents(owner_events, owner_isr); });
180 handled = CaptureUartInterrupt(handled_mask);
184uint32_t IRAM_ATTR ESP32UART::CaptureUartInterrupt(uint32_t mask)
186 esp_os_enter_critical_safe(&irq_lock_);
187 const uint32_t handled = uart_hal_get_intsts_mask(&uart_hal_) & mask;
190 uart_hal_disable_intr_mask(&uart_hal_, handled);
193 uart_hal_clr_intsts_mask(&uart_hal_, handled);
195 esp_os_exit_critical_safe(&irq_lock_);
ESP32UART(uart_port_t uart_num, int tx_pin, int rx_pin, int rts_pin=PIN_NO_CHANGE, int cts_pin=PIN_NO_CHANGE, size_t rx_buffer_size=1024, size_t tx_buffer_size=512, uint32_t tx_queue_size=5, UART::Configuration config={115200, UART::Parity::NO_PARITY, 8, 1}, bool enable_dma=true)
构造并初始化 ESP UART / Construct and initialize an ESP UART.
size_t PopWithWriter(size_t limit, Writer &&writer)
通过回调取走队头前缀 / Consume a front prefix through a callback.
WriteQueue GetWriteQueue(bool in_isr=false)
获取已提交队头的出队接口 / Obtain a consumer interface for the released front.
size_t Size() const
获取字节队列当前数据量 / Get current byte queue occupancy.
LibXR 命名空间 / LibXR namespace.
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ INIT_ERR
初始化错误 / Initialization error
@ OK
操作成功 / Operation successful