7#include "double_buffer.hpp"
8#include "driver/gpio.h"
10#include "esp_intr_alloc.h"
12#include "hal/uart_hal.h"
13#include "hal/uart_types.h"
14#include "soc/periph_defs.h"
15#include "soc/soc_caps.h"
18#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
19#include "esp_private/gdma.h"
20#include "esp_private/gdma_link.h"
21#include "hal/uhci_hal.h"
88 size_t tx_buffer_size = 512, uint32_t tx_queue_size = 5,
90 bool enable_dma =
true);
153#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
158 static bool DmaTxEofCallback(gdma_channel_handle_t dma_chan,
159 gdma_event_data_t* event_data,
void* user_data);
165 static bool DmaTxDescrErrCallback(gdma_channel_handle_t dma_chan,
166 gdma_event_data_t* event_data,
void* user_data);
172 static bool DmaRxDoneCallback(gdma_channel_handle_t dma_chan,
173 gdma_event_data_t* event_data,
void* user_data);
179 static bool DmaRxDescrErrCallback(gdma_channel_handle_t dma_chan,
180 gdma_event_data_t* event_data,
void* user_data);
207#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
224 void HandleDmaRxDone(gdma_event_data_t* event_data);
230 void HandleDmaRxError();
236 void HandleDmaTxError();
242 void PushDmaRxData(
size_t recv_size,
bool in_isr);
316 void PushRxBytes(
const uint8_t* data,
size_t size,
bool in_isr);
377#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
378 bool dma_backend_enabled_ =
false;
379 uhci_hal_context_t uhci_hal_ = {};
380 gdma_channel_handle_t tx_dma_channel_ =
nullptr;
381 gdma_channel_handle_t rx_dma_channel_ =
nullptr;
382 uintptr_t tx_dma_head_addr_[2] = {0U, 0U};
383 gdma_link_list_handle_t rx_dma_link_ =
nullptr;
384 uint8_t* rx_dma_storage_ =
nullptr;
385 size_t rx_dma_chunk_size_ = 0;
386 uint32_t rx_dma_node_index_ = 0;
双缓冲区管理类 / Double buffer manager class
ESP32 UART backend with FIFO and optional GDMA fast paths.
static ErrorCode ResolveUartPeriph(uart_port_t uart_num, periph_module_t &out)
Map one UART index to its peripheral module.
ErrorCode TryStartTx(bool in_isr)
Try to start queued transmit work.
ErrorCode SetConfig(UART::Configuration config) override
Apply a new UART framing and baud configuration.
UART::Configuration config_
Current UART framing configuration.
ErrorCode SetLoopback(bool enable)
Toggle UART peripheral internal loopback mode.
void HandleUartInterrupt()
Dispatch pending UART interrupt reasons.
int rx_pin_
RX GPIO pin or PIN_NO_CHANGE.
int tx_pin_
TX GPIO pin or PIN_NO_CHANGE.
bool LoadActiveTxFromQueue(bool in_isr)
Load one active TX request from the queue.
void ConfigureRxInterruptPath()
Program RX interrupt thresholds and masks.
bool dma_requested_
Constructor preference for DMA mode.
intr_handle_t uart_intr_handle_
Registered UART interrupt handle.
Flag::Plain tx_busy_
Hardware TX engine currently owns the request.
bool StartActiveTransfer(bool in_isr)
Start the active request on the selected TX backend.
uint8_t * rx_isr_buffer_
Scratch buffer used by the RX ISR path.
uart_hal_context_t uart_hal_
ESP-IDF UART HAL context.
uint8_t * tx_storage_
Backing storage for the TX half-buffers.
ErrorCode InitUartHardware()
Initialize UART hardware and base HAL state.
static uart_parity_t ResolveParity(UART::Parity parity)
Convert configured parity into the HAL enum.
size_t rx_isr_buffer_size_
Size of rx_isr_buffer_.
void FillTxFifo(bool in_isr)
Drain active TX bytes into the UART FIFO backend.
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.
bool tx_active_valid_
Whether the active TX metadata is valid.
void OnTxTransferDone(bool in_isr, ErrorCode result)
Finalize one TX transfer result.
WritePort _write_port
Write-side queue bridge exposed to UART.
void DrainRxFifo(bool in_isr)
Drain pending bytes from the hardware RX FIFO.
WriteInfoBlock tx_active_info_
Metadata for the active TX request.
void HandleTxInterrupt(uint32_t uart_intr_status)
Handle TX-side UART interrupt reasons.
int cts_pin_
CTS GPIO pin or PIN_NO_CHANGE.
bool LoadPendingTxFromQueue(bool in_isr)
Preload one pending TX request for DMA mode.
Flag::Plain in_tx_isr_
Reentry guard while processing TX ISR work.
bool StartAndReportActive(bool in_isr)
Start the active request and report queue completion ownership.
int rts_pin_
RTS GPIO pin or PIN_NO_CHANGE.
bool StartPendingTxIfIdle(bool in_isr)
Start the current pending DMA request when TX is fully idle.
void HandleRxInterrupt(uint32_t uart_intr_status)
Handle RX-side UART interrupt reasons.
bool DequeueTxToBuffer(uint8_t *buffer, size_t &size, WriteInfoBlock &info, bool in_isr)
Dequeue one TX payload into the selected buffer.
ESP32UARTReadPort _read_port
Read-side queue bridge exposed to UART.
DoubleBuffer tx_dma_buffer_
TX double-buffer view for the DMA path.
bool uart_isr_installed_
UART ISR installation state.
void ClearActiveTx()
Clear active TX state.
static uint8_t * AllocateTxStorage(size_t size)
Allocate DMA-capable backing storage for TX buffers.
static bool ResolveStopBits(uint8_t stop_bits, uart_stop_bits_t &out)
Convert configured stop bits into the HAL enum.
uart_port_t uart_num_
Selected UART peripheral index.
size_t tx_active_offset_
Bytes already emitted for the active request.
bool PromotePendingTxToActive()
Promote one preloaded DMA pending request into the active slot.
static bool ResolveWordLength(uint8_t data_bits, uart_word_length_t &out)
Convert configured data bits into the HAL enum.
bool uart_hw_enabled_
UART hardware block was initialized.
void PushRxBytes(const uint8_t *data, size_t size, bool in_isr)
Push RX bytes into the software queue.
size_t tx_active_length_
Active TX payload length in bytes.
static constexpr int PIN_NO_CHANGE
Sentinel for an unmapped GPIO.
void ClearPendingTx()
Clear pending TX state.
ErrorCode InstallUartIsr()
Install the UART interrupt handler.
ErrorCode ConfigurePins()
Configure the selected GPIO pins.
Flag::Atomic rx_fifo_draining_
RX FIFO drain reentry gate.
static void UartIsrEntry(void *arg)
UART ISR trampoline.
ESP32 UART 读端口 / ESP32 UART read port.
ESP32UART & owner_
所属 UART 后端 / Owning UART backend
void OnRxDequeue(bool in_isr) override
软件队列出队后的回调 / Callback after software RX dequeue
ESP32UARTReadPort(size_t size, ESP32UART &owner)
构造读端口 / Construct the read port
普通标志位(非原子)/ Non-atomic flag
ReadPort class for handling read operations.
ReadPort & operator=(ReadFun fun)
赋值运算符重载,用于设置读取函数。 Overloaded assignment operator to set the read function.
通用异步收发传输(UART)基类 / Abstract base class for Universal Asynchronous Receiver-Transmitter (UART)
Parity
奇偶校验模式 / Parity mode
@ NO_PARITY
无校验 / No parity
WritePort class for handling write operations.
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.
UART 配置结构体 / UART configuration structure.