libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::ESP32UART Class Reference

ESP32 UART backend with FIFO and optional GDMA fast paths. More...

#include <esp_uart.hpp>

Inheritance diagram for LibXR::ESP32UART:
[legend]
Collaboration diagram for LibXR::ESP32UART:
[legend]

Public Member Functions

 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)
 Create and initialize one ESP32 UART instance.
 
ErrorCode SetConfig (UART::Configuration config) override
 Apply a new UART framing and baud configuration.
 
ErrorCode SetLoopback (bool enable)
 Toggle UART peripheral internal loopback mode.
 
- Public Member Functions inherited from LibXR::UART
template<typename ReadPortType = ReadPort, typename WritePortType = WritePort>
 UART (ReadPortType *read_port, WritePortType *write_port)
 UART 构造函数 / UART constructor.
 
template<typename OperationType , typename = std::enable_if_t<std::is_base_of_v< WriteOperation, std::decay_t<OperationType>>>>
ErrorCode Write (ConstRawData data, OperationType &&op, bool in_isr=false)
 
template<typename OperationType , typename = std::enable_if_t<std::is_base_of_v< ReadOperation, std::decay_t<OperationType>>>>
ErrorCode Read (RawData data, OperationType &&op, bool in_isr=false)
 

Static Public Member Functions

static ErrorCode WriteFun (WritePort &port, bool in_isr)
 Queue-driven TX entry used by WritePort.
 
static ErrorCode ReadFun (ReadPort &port, bool in_isr)
 Queue-driven RX entry used by ReadPort.
 

Static Public Attributes

static constexpr int PIN_NO_CHANGE = -1
 Sentinel for an unmapped GPIO.
 

Private Member Functions

ErrorCode InitUartHardware ()
 Initialize UART hardware and base HAL state.
 
ErrorCode ConfigurePins ()
 Configure the selected GPIO pins.
 
ErrorCode InstallUartIsr ()
 Install the UART interrupt handler.
 
void ConfigureRxInterruptPath ()
 Program RX interrupt thresholds and masks.
 
ErrorCode TryStartTx (bool in_isr)
 Try to start queued transmit work.
 
bool LoadActiveTxFromQueue (bool in_isr)
 Load one active TX request from the queue.
 
bool LoadPendingTxFromQueue (bool in_isr)
 Preload one pending TX request for DMA mode.
 
bool PromotePendingTxToActive ()
 Promote one preloaded DMA pending request into the active slot.
 
bool StartPendingTxIfIdle (bool in_isr)
 Start the current pending DMA request when TX is fully idle.
 
bool DequeueTxToBuffer (uint8_t *buffer, size_t &size, WriteInfoBlock &info, bool in_isr)
 Dequeue one TX payload into the selected buffer.
 
bool StartActiveTransfer (bool in_isr)
 Start the active request on the selected TX backend.
 
bool StartAndReportActive (bool in_isr)
 Start the active request and report queue completion ownership.
 
void ClearActiveTx ()
 Clear active TX state.
 
void ClearPendingTx ()
 Clear pending TX state.
 
void FillTxFifo (bool in_isr)
 Drain active TX bytes into the UART FIFO backend.
 
void PushRxBytes (const uint8_t *data, size_t size, bool in_isr)
 Push RX bytes into the software queue.
 
void DrainRxFifo (bool in_isr)
 Drain pending bytes from the hardware RX FIFO.
 
void HandleRxInterrupt (uint32_t uart_intr_status)
 Handle RX-side UART interrupt reasons.
 
void HandleTxInterrupt (uint32_t uart_intr_status)
 Handle TX-side UART interrupt reasons.
 
void HandleUartInterrupt ()
 Dispatch pending UART interrupt reasons.
 
void OnTxTransferDone (bool in_isr, ErrorCode result)
 Finalize one TX transfer result.
 

Static Private Member Functions

static uint8_t * AllocateTxStorage (size_t size)
 Allocate DMA-capable backing storage for TX buffers.
 
static ErrorCode ResolveUartPeriph (uart_port_t uart_num, periph_module_t &out)
 Map one UART index to its peripheral module.
 
static bool ResolveWordLength (uint8_t data_bits, uart_word_length_t &out)
 Convert configured data bits into the HAL enum.
 
static bool ResolveStopBits (uint8_t stop_bits, uart_stop_bits_t &out)
 Convert configured stop bits into the HAL enum.
 
static uart_parity_t ResolveParity (UART::Parity parity)
 Convert configured parity into the HAL enum.
 
static void UartIsrEntry (void *arg)
 UART ISR trampoline.
 

Private Attributes

uart_port_t uart_num_
 Selected UART peripheral index.
 
int tx_pin_
 TX GPIO pin or PIN_NO_CHANGE.
 
int rx_pin_
 RX GPIO pin or PIN_NO_CHANGE.
 
int rts_pin_
 RTS GPIO pin or PIN_NO_CHANGE.
 
int cts_pin_
 CTS GPIO pin or PIN_NO_CHANGE.
 
UART::Configuration config_
 Current UART framing configuration.
 
uint8_t * rx_isr_buffer_ = nullptr
 Scratch buffer used by the RX ISR path.
 
size_t rx_isr_buffer_size_ = 0
 Size of rx_isr_buffer_.
 
uint8_t * tx_storage_ = nullptr
 Backing storage for the TX half-buffers.
 
DoubleBuffer tx_dma_buffer_ {}
 TX double-buffer view for the DMA path.
 
WriteInfoBlock tx_active_info_ = {}
 Metadata for the active TX request.
 
size_t tx_active_length_ = 0U
 Active TX payload length in bytes.
 
size_t tx_active_offset_ = 0U
 Bytes already emitted for the active request.
 
bool tx_active_valid_ = false
 Whether the active TX metadata is valid.
 
Flag::Plain tx_busy_
 Hardware TX engine currently owns the request.
 
Flag::Plain in_tx_isr_
 Reentry guard while processing TX ISR work.
 
bool uart_hw_enabled_ = false
 UART hardware block was initialized.
 
uart_hal_context_t uart_hal_ = {}
 ESP-IDF UART HAL context.
 
intr_handle_t uart_intr_handle_ = nullptr
 Registered UART interrupt handle.
 
bool uart_isr_installed_ = false
 UART ISR installation state.
 
bool dma_requested_ = true
 Constructor preference for DMA mode.
 
ESP32UARTReadPort _read_port
 Read-side queue bridge exposed to UART.
 
WritePort _write_port
 Write-side queue bridge exposed to UART.
 
Flag::Atomic rx_fifo_draining_ {}
 RX FIFO drain reentry gate.
 

Friends

class ESP32UARTReadPort
 

Additional Inherited Members

- Public Types inherited from LibXR::UART
enum class  Parity : uint8_t { NO_PARITY = 0 , EVEN = 1 , ODD = 2 }
 奇偶校验模式 / Parity mode More...
 
- Data Fields inherited from LibXR::UART
ReadPortread_port_
 读取端口 / Read port
 
WritePortwrite_port_
 写入端口 / Write port
 

Detailed Description

ESP32 UART backend with FIFO and optional GDMA fast paths.

ESP32 UART 后端,支持 FIFO 和可选 GDMA 快路径。

The object owns the UART hardware state, software queue plumbing, and the optional DMA resources used by the ESP-specific transmit and receive paths. 该对象持有 UART 硬件状态、软件队列连接,以及 ESP 专用收发路径使用的可选 DMA 资源。

Definition at line 75 of file esp_uart.hpp.

Constructor & Destructor Documentation

◆ ESP32UART()

LibXR::ESP32UART::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 )

Create and initialize one ESP32 UART instance.

创建并初始化一个 ESP32 UART 实例。

Definition at line 104 of file esp_uart.cpp.

108 uart_num_(uart_num),
109 tx_pin_(tx_pin),
110 rx_pin_(rx_pin),
111 rts_pin_(rts_pin),
112 cts_pin_(cts_pin),
113 config_(config),
114 rx_isr_buffer_(new uint8_t[rx_buffer_size]),
115 rx_isr_buffer_size_(rx_buffer_size),
116 tx_storage_(AllocateTxStorage(tx_buffer_size * 2)),
117 dma_requested_(enable_dma),
118 _read_port(rx_buffer_size, *this),
119 _write_port(tx_queue_size, tx_buffer_size)
120{
121 ASSERT(!IsConsoleUartInUse(uart_num_));
122 ASSERT(uart_num_ < UART_NUM_MAX);
123 ASSERT(uart_num_ < SOC_UART_HP_NUM);
124 ASSERT(rx_isr_buffer_size_ > 0);
125 ASSERT(tx_buffer_size > 0);
126
127 tx_dma_buffer_.Init({tx_storage_, tx_buffer_size * 2U});
128
131
133 {
134 ASSERT(false);
135 return;
136 }
137
138#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
139 if (dma_requested_)
140 {
141 if (InitDmaBackend() != ErrorCode::OK)
142 {
143 ASSERT(false);
144 return;
145 }
146 }
147
148 if (!dma_backend_enabled_)
149 {
151 {
152 ASSERT(false);
153 return;
154 }
156 }
157#else
159 {
160 ASSERT(false);
161 return;
162 }
164#endif
165}
void Init(const LibXR::RawData &raw_data)
绑定连续 backing storage 并重置双缓冲状态 Binds continuous backing storage and resets double-buffer state
UART::Configuration config_
Current UART framing configuration.
Definition esp_uart.hpp:354
int rx_pin_
RX GPIO pin or PIN_NO_CHANGE.
Definition esp_uart.hpp:350
int tx_pin_
TX GPIO pin or PIN_NO_CHANGE.
Definition esp_uart.hpp:349
void ConfigureRxInterruptPath()
Program RX interrupt thresholds and masks.
Definition esp_uart.cpp:170
bool dma_requested_
Constructor preference for DMA mode.
Definition esp_uart.hpp:372
uint8_t * rx_isr_buffer_
Scratch buffer used by the RX ISR path.
Definition esp_uart.hpp:356
uint8_t * tx_storage_
Backing storage for the TX half-buffers.
Definition esp_uart.hpp:359
ErrorCode InitUartHardware()
Initialize UART hardware and base HAL state.
Definition esp_uart.cpp:351
size_t rx_isr_buffer_size_
Size of rx_isr_buffer_.
Definition esp_uart.hpp:357
WritePort _write_port
Write-side queue bridge exposed to UART.
Definition esp_uart.hpp:375
int cts_pin_
CTS GPIO pin or PIN_NO_CHANGE.
Definition esp_uart.hpp:352
int rts_pin_
RTS GPIO pin or PIN_NO_CHANGE.
Definition esp_uart.hpp:351
ESP32UARTReadPort _read_port
Read-side queue bridge exposed to UART.
Definition esp_uart.hpp:374
DoubleBuffer tx_dma_buffer_
TX double-buffer view for the DMA path.
Definition esp_uart.hpp:360
static uint8_t * AllocateTxStorage(size_t size)
Allocate DMA-capable backing storage for TX buffers.
Definition esp_uart.cpp:66
uart_port_t uart_num_
Selected UART peripheral index.
Definition esp_uart.hpp:348
ErrorCode InstallUartIsr()
Install the UART interrupt handler.
UART(ReadPortType *read_port, WritePortType *write_port)
UART 构造函数 / UART constructor.
Definition uart.hpp:66
@ OK
操作成功 | Operation successful
ErrorCode(* ReadFun)(ReadPort &port, bool in_isr)
Function pointer type for read notifications.
ErrorCode(* WriteFun)(WritePort &port, bool in_isr)
Function pointer type for write operations.

Member Function Documentation

◆ AllocateTxStorage()

uint8_t * LibXR::ESP32UART::AllocateTxStorage ( size_t size)
staticprivate

Allocate DMA-capable backing storage for TX buffers.

为 TX buffer 分配可 DMA 访问的 backing storage。

Definition at line 66 of file esp_uart.cpp.

67{
68 void* aligned = heap_caps_aligned_alloc(
69 4, size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT);
70 if (aligned != nullptr)
71 {
72 return static_cast<uint8_t*>(aligned);
73 }
74
75 return static_cast<uint8_t*>(
76 heap_caps_malloc(size, MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA | MALLOC_CAP_8BIT));
77}

◆ ClearActiveTx()

void IRAM_ATTR LibXR::ESP32UART::ClearActiveTx ( )
private

Clear active TX state.

清除 active TX 状态。

Definition at line 451 of file esp_uart.cpp.

452{
455 tx_active_info_ = {};
456 tx_active_valid_ = false;
457}
bool tx_active_valid_
Whether the active TX metadata is valid.
Definition esp_uart.hpp:364
WriteInfoBlock tx_active_info_
Metadata for the active TX request.
Definition esp_uart.hpp:361
size_t tx_active_offset_
Bytes already emitted for the active request.
Definition esp_uart.hpp:363
size_t tx_active_length_
Active TX payload length in bytes.
Definition esp_uart.hpp:362

◆ ClearPendingTx()

void IRAM_ATTR LibXR::ESP32UART::ClearPendingTx ( )
private

Clear pending TX state.

清除 pending TX 状态。

Definition at line 461 of file esp_uart.cpp.

462{
463#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
464 if (dma_backend_enabled_)
465 {
467 }
468#endif
469}
void Reset()
重置 active/pending 状态,但保留已绑定的 backing storage Resets active/pending state while keeping bound backing ...

◆ ConfigurePins()

ErrorCode LibXR::ESP32UART::ConfigurePins ( )
private

Configure the selected GPIO pins.

配置选定的 GPIO 引脚。

Definition at line 399 of file esp_uart.cpp.

400{
401 if (tx_pin_ >= 0)
402 {
403 if (!GPIO_IS_VALID_OUTPUT_GPIO(tx_pin_))
404 {
405 return ErrorCode::ARG_ERR;
406 }
407 esp_rom_gpio_pad_select_gpio(static_cast<uint32_t>(tx_pin_));
408 esp_rom_gpio_connect_out_signal(
409 tx_pin_, UART_PERIPH_SIGNAL(uart_num_, SOC_UART_TX_PIN_IDX), false, false);
410 }
411
412 if (rx_pin_ >= 0)
413 {
414 if (!GPIO_IS_VALID_GPIO(rx_pin_))
415 {
416 return ErrorCode::ARG_ERR;
417 }
418 gpio_input_enable(static_cast<gpio_num_t>(rx_pin_));
419 esp_rom_gpio_connect_in_signal(
420 rx_pin_, UART_PERIPH_SIGNAL(uart_num_, SOC_UART_RX_PIN_IDX), false);
421 }
422
423 if (rts_pin_ >= 0)
424 {
425 if (!GPIO_IS_VALID_OUTPUT_GPIO(rts_pin_))
426 {
427 return ErrorCode::ARG_ERR;
428 }
429 esp_rom_gpio_pad_select_gpio(static_cast<uint32_t>(rts_pin_));
430 esp_rom_gpio_connect_out_signal(
431 rts_pin_, UART_PERIPH_SIGNAL(uart_num_, SOC_UART_RTS_PIN_IDX), false, false);
432 }
433
434 if (cts_pin_ >= 0)
435 {
436 if (!GPIO_IS_VALID_GPIO(cts_pin_))
437 {
438 return ErrorCode::ARG_ERR;
439 }
440 gpio_pullup_en(static_cast<gpio_num_t>(cts_pin_));
441 gpio_input_enable(static_cast<gpio_num_t>(cts_pin_));
442 esp_rom_gpio_connect_in_signal(
443 cts_pin_, UART_PERIPH_SIGNAL(uart_num_, SOC_UART_CTS_PIN_IDX), false);
444 }
445
446 return ErrorCode::OK;
447}
@ ARG_ERR
参数错误 | Argument error

◆ ConfigureRxInterruptPath()

void LibXR::ESP32UART::ConfigureRxInterruptPath ( )
private

Program RX interrupt thresholds and masks.

配置 RX 中断阈值和掩码。

Definition at line 170 of file esp_uart.cpp.

171{
172 const uint16_t full_thr = static_cast<uint16_t>(SOC_UART_FIFO_LEN / 2U);
173
174 uart_hal_set_rxfifo_full_thr(&uart_hal_, full_thr);
175 uart_hal_set_rx_timeout(&uart_hal_, RX_TOUT_THRESHOLD);
176 uart_hal_clr_intsts_mask(&uart_hal_, UART_RX_INTR_MASK);
177 uart_hal_ena_intr_mask(&uart_hal_, UART_RX_INTR_MASK);
178}
uart_hal_context_t uart_hal_
ESP-IDF UART HAL context.
Definition esp_uart.hpp:369

◆ DequeueTxToBuffer()

bool IRAM_ATTR LibXR::ESP32UART::DequeueTxToBuffer ( uint8_t * buffer,
size_t & size,
WriteInfoBlock & info,
bool in_isr )
private

Dequeue one TX payload into the selected buffer.

将一个 TX payload 出队到选定缓冲区。

Definition at line 684 of file esp_uart.cpp.

686{
687 (void)in_isr;
688 (void)buffer;
689
690 WriteInfoBlock peek_info = {};
691 if (write_port_->queue_info_->Peek(peek_info) != ErrorCode::OK)
692 {
693 return false;
694 }
695
696 size_t max_size = write_port_->queue_data_->MaxSize();
697#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
698 if (dma_backend_enabled_)
699 {
700 max_size = tx_dma_buffer_.Size();
701 }
702#endif
703 if (peek_info.data.size_ > max_size)
704 {
705 ASSERT(false);
706 return false;
707 }
708
709#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
710 if (dma_backend_enabled_)
711 {
712 if (write_port_->queue_data_->PopBatch(buffer, peek_info.data.size_) != ErrorCode::OK)
713 {
714 return false;
715 }
716 }
717#endif
718
719 if (write_port_->queue_info_->Pop(info) != ErrorCode::OK)
720 {
721 return false;
722 }
723
724 size = peek_info.data.size_;
725 return true;
726}
size_t Size() const
获取每个缓冲区的大小(单位:字节) Gets the size of each buffer in bytes
size_t MaxSize() const
获取队列最大容量 / Get the maximum queue capacity
ErrorCode PopBatch(Data *data, size_t size)
批量弹出多个 payload。
WritePort * write_port_
写入端口 / Write port
Definition uart.hpp:54
SPSCQueue< WriteInfoBlock > * queue_info_
Metadata queue for pending write batches. 挂起写批次的元数据队列。
SPSCQueue< uint8_t > * queue_data_
Payload queue for pending write bytes. 挂起写入字节的数据队列。

◆ DrainRxFifo()

void IRAM_ATTR LibXR::ESP32UART::DrainRxFifo ( bool in_isr)
private

Drain pending bytes from the hardware RX FIFO.

从硬件 RX FIFO 中取出待处理字节。

Definition at line 118 of file esp_uart_fifo.cpp.

119{
121 {
122 return;
123 }
124
125 bool pushed_any = false;
126 while (uart_hal_get_rxfifo_len(&uart_hal_) > 0U)
127 {
128 const size_t fifo_len = uart_hal_get_rxfifo_len(&uart_hal_);
129 const size_t write_len = std::min(fifo_len, read_port_->queue_data_->EmptySize());
130 if (write_len == 0U)
131 {
132 break;
133 }
134
136 write_len,
137 [this](uint8_t* buffer, size_t chunk_size) -> ErrorCode
138 {
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
143 });
144
145 if ((push_ec == ErrorCode::FULL) || (push_ec == ErrorCode::EMPTY))
146 {
147 break;
148 }
149 if (push_ec != ErrorCode::OK)
150 {
151 ASSERT(false);
152 break;
153 }
154
155 pushed_any = true;
156 }
157
158 if (pushed_any)
159 {
161 }
162
164}
Flag::Atomic rx_fifo_draining_
RX FIFO drain reentry gate.
Definition esp_uart.hpp:389
bool TestAndSet() noexcept
测试并置位:置位并返回旧状态 / Test-and-set: set and return previous state
Definition flag.hpp:66
void Clear() noexcept
清除标志 / Clear the flag
Definition flag.hpp:47
SPSCQueue< uint8_t > * queue_data_
RX payload queue. 接收数据字节队列。
Definition read_port.hpp:55
void ProcessPendingReads(bool in_isr)
Processes pending reads.
size_t EmptySize() const
获取剩余空槽数 / Get the current free-slot count
ErrorCode PushWithWriter(Writer &&writer)
通过写入器回调推入一个 payload。
ReadPort * read_port_
读取端口 / Read port
Definition uart.hpp:53
ErrorCode
定义错误码枚举
@ EMPTY
为空 | Empty
@ FULL
已满 | Full

◆ FillTxFifo()

void IRAM_ATTR LibXR::ESP32UART::FillTxFifo ( bool in_isr)
private

Drain active TX bytes into the UART FIFO backend.

将 active TX 字节排入 UART FIFO 后端。

Definition at line 68 of file esp_uart_fifo.cpp.

69{
71 {
72 return;
73 }
74
76 {
77 const uint32_t fifo_space = uart_hal_get_txfifo_len(&uart_hal_);
78 if (fifo_space == 0U)
79 {
80 break;
81 }
82
83 const size_t remaining = tx_active_length_ - tx_active_offset_;
84 const size_t chunk_size = std::min<size_t>(remaining, fifo_space);
85
87 chunk_size,
88 [this](const uint8_t* src, size_t size) -> ErrorCode
89 {
90 uint32_t write_size = 0;
91 uart_hal_write_txfifo(&uart_hal_, src, static_cast<uint32_t>(size),
92 &write_size);
93 return (write_size == static_cast<uint32_t>(size)) ? ErrorCode::OK
95 });
96 if (pop_ec != ErrorCode::OK)
97 {
98 ASSERT(false);
99 break;
100 }
101
102 tx_active_offset_ += chunk_size;
103 }
104
105 if ((tx_active_offset_ < tx_active_length_) || !in_isr)
106 {
107 return;
108 }
109
110 uart_hal_disable_intr_mask(&uart_hal_, UART_INTR_TXFIFO_EMPTY);
112}
void OnTxTransferDone(bool in_isr, ErrorCode result)
Finalize one TX transfer result.
Definition esp_uart.cpp:807
ErrorCode PopWithReader(Reader &&reader)
通过读取器回调弹出一个 payload。

◆ HandleRxInterrupt()

void IRAM_ATTR LibXR::ESP32UART::HandleRxInterrupt ( uint32_t uart_intr_status)
private

Handle RX-side UART interrupt reasons.

处理 RX 侧 UART 中断原因。

Definition at line 170 of file esp_uart_fifo.cpp.

171{
172 const bool has_overflow = (uart_intr_status & UART_INTR_RXFIFO_OVF) != 0U;
173 const bool has_rx_data =
174 (uart_intr_status & (UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT)) != 0U;
175
176 if (!has_overflow && !has_rx_data)
177 {
178 return;
179 }
180
181 if (has_overflow)
182 {
183 // Overrun means at least one incoming byte was dropped. Keep remaining FIFO
184 // bytes to minimize extra loss instead of resetting the whole RX FIFO.
185 uart_hal_clr_intsts_mask(&uart_hal_, UART_INTR_RXFIFO_OVF);
186 }
187
188 DrainRxFifo(true);
189 uart_hal_clr_intsts_mask(&uart_hal_, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT);
190}
void DrainRxFifo(bool in_isr)
Drain pending bytes from the hardware RX FIFO.

◆ HandleTxInterrupt()

void IRAM_ATTR LibXR::ESP32UART::HandleTxInterrupt ( uint32_t uart_intr_status)
private

Handle TX-side UART interrupt reasons.

处理 TX 侧 UART 中断原因。

Definition at line 195 of file esp_uart_fifo.cpp.

196{
197 if ((uart_intr_status & UART_INTR_TXFIFO_EMPTY) == 0U)
198 {
199 return;
200 }
201
202 Flag::ScopedRestore tx_flag(in_tx_isr_);
203 FillTxFifo(true);
204 uart_hal_clr_intsts_mask(&uart_hal_, UART_INTR_TXFIFO_EMPTY);
205}
void FillTxFifo(bool in_isr)
Drain active TX bytes into the UART FIFO backend.
Flag::Plain in_tx_isr_
Reentry guard while processing TX ISR work.
Definition esp_uart.hpp:366

◆ HandleUartInterrupt()

void IRAM_ATTR LibXR::ESP32UART::HandleUartInterrupt ( )
private

Dispatch pending UART interrupt reasons.

分发待处理的 UART 中断原因。

Definition at line 211 of file esp_uart_fifo.cpp.

212{
213 uint32_t uart_intr_status = uart_hal_get_intsts_mask(&uart_hal_);
214
215 while (uart_intr_status != 0)
216 {
217 if (uart_intr_status & UART_RX_INTR_MASK)
218 {
219 HandleRxInterrupt(uart_intr_status);
220 }
221
222 if (uart_intr_status & UART_TX_INTR_MASK)
223 {
224 HandleTxInterrupt(uart_intr_status);
225 }
226
227 uart_intr_status = uart_hal_get_intsts_mask(&uart_hal_);
228 }
229}
void HandleTxInterrupt(uint32_t uart_intr_status)
Handle TX-side UART interrupt reasons.
void HandleRxInterrupt(uint32_t uart_intr_status)
Handle RX-side UART interrupt reasons.

◆ InitUartHardware()

ErrorCode LibXR::ESP32UART::InitUartHardware ( )
private

Initialize UART hardware and base HAL state.

初始化 UART 硬件和基础 HAL 状态。

Definition at line 351 of file esp_uart.cpp.

352{
353 if (uart_num_ >= UART_NUM_MAX)
354 {
356 }
357
358 periph_module_t uart_module = PERIPH_MODULE_MAX;
359 if (ResolveUartPeriph(uart_num_, uart_module) != ErrorCode::OK)
360 {
362 }
363
364 uart_hal_.dev = UART_LL_GET_HW(uart_num_);
365 if (uart_hal_.dev == nullptr)
366 {
368 }
369
370 periph_module_enable(uart_module);
371 periph_module_reset(uart_module);
372
373 uart_ll_sclk_enable(uart_hal_.dev);
374 uart_hal_init(&uart_hal_, uart_num_);
375
376 uart_hw_enabled_ = true;
378 {
379 uart_hw_enabled_ = false;
380 return ErrorCode::INIT_ERR;
381 }
382
384 {
385 uart_hw_enabled_ = false;
386 return ErrorCode::INIT_ERR;
387 }
388
389 uart_hal_txfifo_rst(&uart_hal_);
390 uart_hal_rxfifo_rst(&uart_hal_);
391 uart_hal_clr_intsts_mask(&uart_hal_, UINT32_MAX);
392 uart_hal_disable_intr_mask(&uart_hal_, UINT32_MAX);
393
394 return ErrorCode::OK;
395}
static ErrorCode ResolveUartPeriph(uart_port_t uart_num, periph_module_t &out)
Map one UART index to its peripheral module.
Definition esp_uart.cpp:81
ErrorCode SetConfig(UART::Configuration config) override
Apply a new UART framing and baud configuration.
Definition esp_uart.cpp:185
bool uart_hw_enabled_
UART hardware block was initialized.
Definition esp_uart.hpp:368
ErrorCode ConfigurePins()
Configure the selected GPIO pins.
Definition esp_uart.cpp:399
@ INIT_ERR
初始化错误 | Initialization error
@ NOT_SUPPORT
不支持 | Not supported

◆ InstallUartIsr()

ErrorCode LibXR::ESP32UART::InstallUartIsr ( )
private

Install the UART interrupt handler.

安装 UART 中断处理函数。

Definition at line 38 of file esp_uart_fifo.cpp.

39{
41 {
42 return ErrorCode::OK;
43 }
44
45#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3
46 // Classic ESP32/S3 can enter cache-disabled flash windows while UART IRQ is active.
47 // The current WritePort path is not fully IRAM-safe, so keep this IRQ non-IRAM.
48 constexpr int UART_INTR_FLAGS = 0;
49#else
50 constexpr int UART_INTR_FLAGS = ESP_INTR_FLAG_IRAM;
51#endif
52
53 const esp_err_t err = esp_intr_alloc(uart_periph_signal[uart_num_].irq, UART_INTR_FLAGS,
55 if (err != ESP_OK)
56 {
58 }
59
61 return ErrorCode::OK;
62}
intr_handle_t uart_intr_handle_
Registered UART interrupt handle.
Definition esp_uart.hpp:370
bool uart_isr_installed_
UART ISR installation state.
Definition esp_uart.hpp:371
static void UartIsrEntry(void *arg)
UART ISR trampoline.

◆ LoadActiveTxFromQueue()

bool IRAM_ATTR LibXR::ESP32UART::LoadActiveTxFromQueue ( bool in_isr)
private

Load one active TX request from the queue.

从队列装载一个 active TX 请求。

Definition at line 540 of file esp_uart.cpp.

541{
542 (void)in_isr;
543
544 size_t active_length = 0U;
545 WriteInfoBlock active_info = {};
546 uint8_t* active_buffer = nullptr;
547#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
548 if (dma_backend_enabled_)
549 {
550 active_buffer = tx_dma_buffer_.ActiveBuffer();
551 }
552#endif
553 if (!DequeueTxToBuffer(active_buffer, active_length, active_info, in_isr))
554 {
555 return false;
556 }
557
558#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
559 if (dma_backend_enabled_)
560 {
561 tx_dma_buffer_.SetActiveLength(active_length);
562 }
563 else
564#endif
565 {
566 tx_active_length_ = active_length;
567 }
569 tx_active_info_ = active_info;
570 tx_active_valid_ = true;
571 return true;
572}
void SetActiveLength(size_t length)
设置当前活动缓冲区的数据长度 Sets the size of the active buffer
uint8_t * ActiveBuffer() const
获取当前正在使用的缓冲区指针 Returns the currently active buffer
bool DequeueTxToBuffer(uint8_t *buffer, size_t &size, WriteInfoBlock &info, bool in_isr)
Dequeue one TX payload into the selected buffer.
Definition esp_uart.cpp:684

◆ LoadPendingTxFromQueue()

bool IRAM_ATTR LibXR::ESP32UART::LoadPendingTxFromQueue ( bool in_isr)
private

Preload one pending TX request for DMA mode.

为 DMA 模式预装一个 pending TX 请求。

Definition at line 578 of file esp_uart.cpp.

579{
580 (void)in_isr;
581
582#if !(SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED)
583 return false;
584#else
585 if (!dma_backend_enabled_ || tx_dma_buffer_.HasPending())
586 {
587 return false;
588 }
589
590 size_t pending_length = 0U;
591 WriteInfoBlock pending_info = {};
592 if (write_port_->queue_info_->Peek(pending_info) != ErrorCode::OK)
593 {
594 return false;
595 }
596
597 if (pending_info.data.size_ > tx_dma_buffer_.Size())
598 {
599 ASSERT(false);
600 return false;
601 }
602
604 pending_info.data.size_) != ErrorCode::OK)
605 {
606 return false;
607 }
608
609 pending_length = pending_info.data.size_;
610 tx_dma_buffer_.SetPendingLength(pending_length);
612 return true;
613#endif
614}
void SetPendingLength(size_t length)
设置备用缓冲区的数据长度 Sets the size of the pending buffer
void EnablePending()
手动启用 pending 状态 Manually sets the pending state to true
bool HasPending() const
判断是否有待切换的缓冲区 Checks whether a pending buffer is ready
uint8_t * PendingBuffer() const
获取备用缓冲区的指针 Returns the pending (inactive) buffer

◆ OnTxTransferDone()

void IRAM_ATTR LibXR::ESP32UART::OnTxTransferDone ( bool in_isr,
ErrorCode result )
private

Finalize one TX transfer result.

收尾一次 TX 传输结果。

Definition at line 807 of file esp_uart.cpp.

808{
809 Flag::ScopedRestore tx_flag(in_tx_isr_);
810 tx_busy_.Clear();
811
813
814#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
815 if (dma_backend_enabled_)
816 {
817 if ((result != ErrorCode::OK) && tx_dma_buffer_.HasPending())
818 {
819 WriteInfoBlock dropped_info = {};
820 if (write_port_->queue_info_->Pop(dropped_info) == ErrorCode::OK)
821 {
822 write_port_->Finish(in_isr, ErrorCode::FAILED, dropped_info);
823 }
824 else
825 {
826 ASSERT(false);
827 }
829 }
830
831 if (result != ErrorCode::OK)
832 {
833 return;
834 }
835
837 {
838 return;
839 }
840
841 if (!StartAndReportActive(in_isr))
842 {
843 return;
844 }
845
847 {
848 (void)LoadPendingTxFromQueue(in_isr);
849 }
850 return;
851 }
852#endif
853
854 if (result != ErrorCode::OK)
855 {
856 return;
857 }
858
859 if (LoadActiveTxFromQueue(in_isr))
860 {
861 (void)StartAndReportActive(in_isr);
862 }
863}
bool LoadActiveTxFromQueue(bool in_isr)
Load one active TX request from the queue.
Definition esp_uart.cpp:540
Flag::Plain tx_busy_
Hardware TX engine currently owns the request.
Definition esp_uart.hpp:365
bool LoadPendingTxFromQueue(bool in_isr)
Preload one pending TX request for DMA mode.
Definition esp_uart.cpp:578
bool StartAndReportActive(bool in_isr)
Start the active request and report queue completion ownership.
Definition esp_uart.cpp:475
void ClearActiveTx()
Clear active TX state.
Definition esp_uart.cpp:451
bool PromotePendingTxToActive()
Promote one preloaded DMA pending request into the active slot.
Definition esp_uart.cpp:620
void Clear() noexcept
清除标志 / Clear the flag
Definition flag.hpp:130
void Finish(bool in_isr, ErrorCode ans, WriteInfoBlock &info)
更新写入操作的状态。 Updates the status of the write operation.
@ FAILED
操作失败 | Operation failed

◆ PromotePendingTxToActive()

bool IRAM_ATTR LibXR::ESP32UART::PromotePendingTxToActive ( )
private

Promote one preloaded DMA pending request into the active slot.

将一个已经预装的 DMA pending 请求提升到 active 槽位。

Definition at line 620 of file esp_uart.cpp.

621{
622#if !(SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED)
623 return false;
624#else
625 if (!dma_backend_enabled_)
626 {
627 return false;
628 }
629
631 {
632 return false;
633 }
634
635 const size_t pending_length = tx_dma_buffer_.GetPendingLength();
637 tx_dma_buffer_.SetActiveLength(pending_length);
638
640 {
641 ASSERT(false);
642 return false;
643 }
644 tx_active_length_ = pending_length;
646 tx_active_valid_ = true;
647
648 return true;
649#endif
650}
void Switch()
切换到备用缓冲区(若其有效) Switches to the pending buffer if it's valid
size_t GetPendingLength() const
获取 pending 缓冲区中准备好的数据长度 Gets the size of valid data in pending buffer

◆ PushRxBytes()

void IRAM_ATTR LibXR::ESP32UART::PushRxBytes ( const uint8_t * data,
size_t size,
bool in_isr )
private

Push RX bytes into the software queue.

将 RX 字节推入软件队列。

Definition at line 771 of file esp_uart.cpp.

772{
773 size_t offset = 0;
774 bool pushed_any = false;
775 while (offset < size)
776 {
777 const size_t free_space = read_port_->queue_data_->EmptySize();
778 if (free_space == 0)
779 {
780 break;
781 }
782
783 const size_t chunk = std::min(free_space, size - offset);
784 if (read_port_->queue_data_->PushBatch(data + offset, chunk) != ErrorCode::OK)
785 {
786 break;
787 }
788
789 offset += chunk;
790 pushed_any = true;
791 }
792
793 if (pushed_any)
794 {
796 }
797}
ErrorCode PushBatch(const Data *data, size_t size)
批量推入多个 payload。

◆ ReadFun()

ErrorCode LibXR::ESP32UART::ReadFun ( ReadPort & port,
bool in_isr )
static

Queue-driven RX entry used by ReadPort.

ReadPort 使用的队列驱动 RX 入口。

Definition at line 289 of file esp_uart.cpp.

289{ return ErrorCode::PENDING; }
@ PENDING
等待中 | Pending

◆ ResolveParity()

uart_parity_t LibXR::ESP32UART::ResolveParity ( UART::Parity parity)
staticprivate

Convert configured parity into the HAL enum.

将配置的校验位转换为 HAL 枚举。

Definition at line 333 of file esp_uart.cpp.

334{
335 switch (parity)
336 {
338 return UART_PARITY_DISABLE;
340 return UART_PARITY_EVEN;
342 return UART_PARITY_ODD;
343 default:
344 return UART_PARITY_DISABLE;
345 }
346}
@ NO_PARITY
无校验 / No parity
@ ODD
奇校验 / Odd parity
@ EVEN
偶校验 / Even parity

◆ ResolveStopBits()

bool LibXR::ESP32UART::ResolveStopBits ( uint8_t stop_bits,
uart_stop_bits_t & out )
staticprivate

Convert configured stop bits into the HAL enum.

将配置的停止位转换为 HAL 枚举。

Definition at line 316 of file esp_uart.cpp.

317{
318 switch (stop_bits)
319 {
320 case 1:
321 out = UART_STOP_BITS_1;
322 return true;
323 case 2:
324 out = UART_STOP_BITS_2;
325 return true;
326 default:
327 return false;
328 }
329}

◆ ResolveUartPeriph()

ErrorCode LibXR::ESP32UART::ResolveUartPeriph ( uart_port_t uart_num,
periph_module_t & out )
staticprivate

Map one UART index to its peripheral module.

将一个 UART 序号映射到对应的外设模块。

Definition at line 81 of file esp_uart.cpp.

82{
83 switch (uart_num)
84 {
85 case UART_NUM_0:
86 out = PERIPH_UART0_MODULE;
87 return ErrorCode::OK;
88 case UART_NUM_1:
89 out = PERIPH_UART1_MODULE;
90 return ErrorCode::OK;
91#if SOC_UART_HP_NUM > 2
92 case UART_NUM_2:
93 out = PERIPH_UART2_MODULE;
94 return ErrorCode::OK;
95#endif
96 default:
98 }
99}

◆ ResolveWordLength()

bool LibXR::ESP32UART::ResolveWordLength ( uint8_t data_bits,
uart_word_length_t & out )
staticprivate

Convert configured data bits into the HAL enum.

将配置的数据位转换为 HAL 枚举。

Definition at line 293 of file esp_uart.cpp.

294{
295 switch (data_bits)
296 {
297 case 5:
298 out = UART_DATA_5_BITS;
299 return true;
300 case 6:
301 out = UART_DATA_6_BITS;
302 return true;
303 case 7:
304 out = UART_DATA_7_BITS;
305 return true;
306 case 8:
307 out = UART_DATA_8_BITS;
308 return true;
309 default:
310 return false;
311 }
312}

◆ SetConfig()

ErrorCode LibXR::ESP32UART::SetConfig ( UART::Configuration config)
overridevirtual

Apply a new UART framing and baud configuration.

应用新的 UART 帧格式和波特率配置。

Implements LibXR::UART.

Definition at line 185 of file esp_uart.cpp.

186{
187 if (!uart_hw_enabled_)
188 {
190 }
191
192 uart_word_length_t word_length = UART_DATA_8_BITS;
193 uart_stop_bits_t stop_bits = UART_STOP_BITS_1;
194
195 if (!ResolveWordLength(config.data_bits, word_length))
196 {
197 return ErrorCode::ARG_ERR;
198 }
199
200 if (!ResolveStopBits(config.stop_bits, stop_bits))
201 {
202 return ErrorCode::ARG_ERR;
203 }
204
205 const uart_sclk_t sclk = UART_SCLK_DEFAULT;
206 uart_hal_set_sclk(&uart_hal_, static_cast<soc_module_clk_t>(sclk));
207
208 uint32_t sclk_hz = 0;
209 if ((esp_clk_tree_src_get_freq_hz(static_cast<soc_module_clk_t>(sclk),
210 ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED,
211 &sclk_hz) != ESP_OK) ||
212 (sclk_hz == 0))
213 {
214 return ErrorCode::INIT_ERR;
215 }
216
217 if (!uart_hal_set_baudrate(&uart_hal_, config.baudrate, sclk_hz))
218 {
219 return ErrorCode::INIT_ERR;
220 }
221
222 uart_hal_set_data_bit_num(&uart_hal_, word_length);
223 uart_hal_set_stop_bits(&uart_hal_, stop_bits);
224 uart_hal_set_parity(&uart_hal_, ResolveParity(config.parity));
225 uart_hal_set_hw_flow_ctrl(&uart_hal_, UART_HW_FLOWCTRL_DISABLE, 0);
226 uart_hal_set_mode(&uart_hal_, UART_MODE_UART);
227 uart_hal_set_txfifo_empty_thr(&uart_hal_, TX_EMPTY_THRESHOLD);
228 // Drop stale hardware RX FIFO bytes from the previous baud.
229 // Keep software read queue semantics aligned with ST/CH (no read_port reset).
230 uart_hal_rxfifo_rst(&uart_hal_);
231 uart_hal_clr_intsts_mask(&uart_hal_, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT);
232
233#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
234 if (dma_backend_enabled_)
235 {
236 // Re-align the circular RX DMA window after reconfig to avoid
237 // carrying stale pre-switch bytes into the next frame.
238 HandleDmaRxError();
239 }
240#endif
241
242 // Align with ST/CH SetConfig semantics: if TX was in-flight during
243 // reconfiguration, keep transfer progression instead of surfacing BUSY.
245 {
246#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
247 if (dma_backend_enabled_)
248 {
249 (void)StartDmaTx();
250 }
251 else
252#endif
253 {
254 uart_hal_clr_intsts_mask(&uart_hal_, UART_TX_INTR_MASK);
255 uart_hal_ena_intr_mask(&uart_hal_, UART_TX_INTR_MASK);
256 FillTxFifo(false);
257 }
258 }
259
260 config_ = config;
261 return ErrorCode::OK;
262}
static uart_parity_t ResolveParity(UART::Parity parity)
Convert configured parity into the HAL enum.
Definition esp_uart.cpp:333
static bool ResolveStopBits(uint8_t stop_bits, uart_stop_bits_t &out)
Convert configured stop bits into the HAL enum.
Definition esp_uart.cpp:316
static bool ResolveWordLength(uint8_t data_bits, uart_word_length_t &out)
Convert configured data bits into the HAL enum.
Definition esp_uart.cpp:293
bool IsSet() const noexcept
判断是否已置位 / Check whether the flag is set
Definition flag.hpp:138
@ STATE_ERR
状态错误 | State error

◆ SetLoopback()

ErrorCode LibXR::ESP32UART::SetLoopback ( bool enable)

Toggle UART peripheral internal loopback mode.

切换 UART 外设内部环回模式。

Definition at line 267 of file esp_uart.cpp.

268{
269 if (!uart_hw_enabled_)
270 {
272 }
273
274 uart_ll_set_loop_back(uart_hal_.dev, enable);
275 return ErrorCode::OK;
276}

◆ StartActiveTransfer()

bool IRAM_ATTR LibXR::ESP32UART::StartActiveTransfer ( bool in_isr)
private

Start the active request on the selected TX backend.

在选定 TX 后端上启动 active 请求。

Definition at line 734 of file esp_uart.cpp.

735{
736 if (!tx_active_valid_)
737 {
738 return false;
739 }
740
741 if (tx_busy_.TestAndSet())
742 {
743 return true;
744 }
745
747
748#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
749 if (dma_backend_enabled_)
750 {
751 if (StartDmaTx())
752 {
753 return true;
754 }
755
756 tx_busy_.Clear();
757 return false;
758 }
759#endif
760
761 uart_hal_clr_intsts_mask(&uart_hal_, UART_TX_INTR_MASK);
762 uart_hal_ena_intr_mask(&uart_hal_, UART_TX_INTR_MASK);
763 FillTxFifo(false);
764
765 return true;
766}
bool TestAndSet() noexcept
测试并置位:置位并返回旧状态 / Test-and-set: set and return previous state
Definition flag.hpp:146

◆ StartAndReportActive()

bool IRAM_ATTR LibXR::ESP32UART::StartAndReportActive ( bool in_isr)
private

Start the active request and report queue completion ownership.

启动 active 请求并上报队列完成所有权交接。

Definition at line 475 of file esp_uart.cpp.

476{
477 if (!StartActiveTransfer(in_isr))
478 {
481 return false;
482 }
483
484 // Align with STM/CH semantics: once the active write is kicked to HW,
485 // WritePort owns the completion notification and the ISR only advances queues.
487 return true;
488}
bool StartActiveTransfer(bool in_isr)
Start the active request on the selected TX backend.
Definition esp_uart.cpp:734

◆ StartPendingTxIfIdle()

bool IRAM_ATTR LibXR::ESP32UART::StartPendingTxIfIdle ( bool in_isr)
private

Start the current pending DMA request when TX is fully idle.

在 TX 完全空闲时启动当前 pending DMA 请求。

Definition at line 654 of file esp_uart.cpp.

655{
656#if !(SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED)
657 (void)in_isr;
658 return false;
659#else
660 if (!dma_backend_enabled_)
661 {
662 (void)in_isr;
663 return false;
664 }
665
666 if (tx_busy_.IsSet())
667 {
668 return false;
669 }
670
672 {
673 return false;
674 }
675
676 return StartAndReportActive(in_isr);
677#endif
678}

◆ TryStartTx()

ErrorCode IRAM_ATTR LibXR::ESP32UART::TryStartTx ( bool in_isr)
private

Try to start queued transmit work.

尝试启动排队的发送工作。

Definition at line 496 of file esp_uart.cpp.

497{
498 if (in_tx_isr_.IsSet())
499 {
500 return ErrorCode::PENDING;
501 }
502
503#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
504 if (dma_backend_enabled_ && !tx_busy_.IsSet() && StartPendingTxIfIdle(in_isr))
505 {
506 return ErrorCode::PENDING;
507 }
508#endif
509
510 if (!tx_active_valid_)
511 {
512 (void)LoadActiveTxFromQueue(in_isr);
513 }
514
516 {
517 if (!StartActiveTransfer(in_isr))
518 {
520 return ErrorCode::FAILED;
521 }
522
523 return ErrorCode::OK;
524 }
525
526#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
527 if (dma_backend_enabled_ && tx_busy_.IsSet() && !tx_dma_buffer_.HasPending())
528 {
529 (void)LoadPendingTxFromQueue(in_isr);
530 }
531#endif
532
533 return ErrorCode::PENDING;
534}
bool StartPendingTxIfIdle(bool in_isr)
Start the current pending DMA request when TX is fully idle.
Definition esp_uart.cpp:654

◆ UartIsrEntry()

void IRAM_ATTR LibXR::ESP32UART::UartIsrEntry ( void * arg)
staticprivate

UART ISR trampoline.

UART 中断跳板函数。

Definition at line 24 of file esp_uart_fifo.cpp.

25{
26 auto* self = static_cast<ESP32UART*>(arg);
27 if (self != nullptr)
28 {
29 self->HandleUartInterrupt();
30 }
31}
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)
Create and initialize one ESP32 UART instance.
Definition esp_uart.cpp:104

◆ WriteFun()

ErrorCode IRAM_ATTR LibXR::ESP32UART::WriteFun ( WritePort & port,
bool in_isr )
static

Queue-driven TX entry used by WritePort.

WritePort 使用的队列驱动 TX 入口。

Definition at line 280 of file esp_uart.cpp.

281{
282 auto* uart = LibXR::ContainerOf(&port, &ESP32UART::_write_port);
283 return uart->TryStartTx(in_isr);
284}
OwnerType * ContainerOf(MemberType *ptr, MemberType OwnerType::*member) noexcept
通过成员指针恢复其所属对象指针

Friends And Related Symbol Documentation

◆ ESP32UARTReadPort

friend class ESP32UARTReadPort
friend

Definition at line 77 of file esp_uart.hpp.

Field Documentation

◆ _read_port

ESP32UARTReadPort LibXR::ESP32UART::_read_port
private

Read-side queue bridge exposed to UART.

Definition at line 374 of file esp_uart.hpp.

◆ _write_port

WritePort LibXR::ESP32UART::_write_port
private

Write-side queue bridge exposed to UART.

Definition at line 375 of file esp_uart.hpp.

◆ config_

UART::Configuration LibXR::ESP32UART::config_
private

Current UART framing configuration.

Definition at line 354 of file esp_uart.hpp.

◆ cts_pin_

int LibXR::ESP32UART::cts_pin_
private

CTS GPIO pin or PIN_NO_CHANGE.

Definition at line 352 of file esp_uart.hpp.

◆ dma_requested_

bool LibXR::ESP32UART::dma_requested_ = true
private

Constructor preference for DMA mode.

Definition at line 372 of file esp_uart.hpp.

◆ in_tx_isr_

Flag::Plain LibXR::ESP32UART::in_tx_isr_
private

Reentry guard while processing TX ISR work.

Definition at line 366 of file esp_uart.hpp.

◆ PIN_NO_CHANGE

int LibXR::ESP32UART::PIN_NO_CHANGE = -1
staticconstexpr

Sentinel for an unmapped GPIO.

Definition at line 80 of file esp_uart.hpp.

◆ rts_pin_

int LibXR::ESP32UART::rts_pin_
private

RTS GPIO pin or PIN_NO_CHANGE.

Definition at line 351 of file esp_uart.hpp.

◆ rx_fifo_draining_

Flag::Atomic LibXR::ESP32UART::rx_fifo_draining_ {}
private

RX FIFO drain reentry gate.

Definition at line 389 of file esp_uart.hpp.

389{};

◆ rx_isr_buffer_

uint8_t* LibXR::ESP32UART::rx_isr_buffer_ = nullptr
private

Scratch buffer used by the RX ISR path.

Definition at line 356 of file esp_uart.hpp.

◆ rx_isr_buffer_size_

size_t LibXR::ESP32UART::rx_isr_buffer_size_ = 0
private

Size of rx_isr_buffer_.

Definition at line 357 of file esp_uart.hpp.

◆ rx_pin_

int LibXR::ESP32UART::rx_pin_
private

RX GPIO pin or PIN_NO_CHANGE.

Definition at line 350 of file esp_uart.hpp.

◆ tx_active_info_

WriteInfoBlock LibXR::ESP32UART::tx_active_info_ = {}
private

Metadata for the active TX request.

Definition at line 361 of file esp_uart.hpp.

361{};

◆ tx_active_length_

size_t LibXR::ESP32UART::tx_active_length_ = 0U
private

Active TX payload length in bytes.

Definition at line 362 of file esp_uart.hpp.

◆ tx_active_offset_

size_t LibXR::ESP32UART::tx_active_offset_ = 0U
private

Bytes already emitted for the active request.

Definition at line 363 of file esp_uart.hpp.

◆ tx_active_valid_

bool LibXR::ESP32UART::tx_active_valid_ = false
private

Whether the active TX metadata is valid.

Definition at line 364 of file esp_uart.hpp.

◆ tx_busy_

Flag::Plain LibXR::ESP32UART::tx_busy_
private

Hardware TX engine currently owns the request.

Definition at line 365 of file esp_uart.hpp.

◆ tx_dma_buffer_

DoubleBuffer LibXR::ESP32UART::tx_dma_buffer_ {}
private

TX double-buffer view for the DMA path.

Definition at line 360 of file esp_uart.hpp.

360{};

◆ tx_pin_

int LibXR::ESP32UART::tx_pin_
private

TX GPIO pin or PIN_NO_CHANGE.

Definition at line 349 of file esp_uart.hpp.

◆ tx_storage_

uint8_t* LibXR::ESP32UART::tx_storage_ = nullptr
private

Backing storage for the TX half-buffers.

Definition at line 359 of file esp_uart.hpp.

◆ uart_hal_

uart_hal_context_t LibXR::ESP32UART::uart_hal_ = {}
private

ESP-IDF UART HAL context.

Definition at line 369 of file esp_uart.hpp.

369{};

◆ uart_hw_enabled_

bool LibXR::ESP32UART::uart_hw_enabled_ = false
private

UART hardware block was initialized.

Definition at line 368 of file esp_uart.hpp.

◆ uart_intr_handle_

intr_handle_t LibXR::ESP32UART::uart_intr_handle_ = nullptr
private

Registered UART interrupt handle.

Definition at line 370 of file esp_uart.hpp.

◆ uart_isr_installed_

bool LibXR::ESP32UART::uart_isr_installed_ = false
private

UART ISR installation state.

Definition at line 371 of file esp_uart.hpp.

◆ uart_num_

uart_port_t LibXR::ESP32UART::uart_num_
private

Selected UART peripheral index.

Definition at line 348 of file esp_uart.hpp.


The documentation for this class was generated from the following files: