105 size_t tx_buffer_size = 512, uint32_t tx_queue_size = 5,
107 bool enable_dma =
true);
142 static uint8_t* AllocateTxStorage(
size_t size);
148 static ErrorCode ResolveUartPeriph(uart_port_t uart_num, periph_module_t& out);
154 static bool ResolveWordLength(uint8_t data_bits, uart_word_length_t& out);
160 static bool ResolveStopBits(uint8_t stop_bits, uart_stop_bits_t& out);
165 static uart_parity_t ResolveParity(
UART::Parity parity);
170 static void UartIsrEntry(
void* arg);
172#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
176 static bool DmaTxEofCallback(gdma_channel_handle_t dma_chan,
177 gdma_event_data_t* event_data,
void* user_data);
182 static bool DmaTxDescrErrCallback(gdma_channel_handle_t dma_chan,
183 gdma_event_data_t* event_data,
void* user_data);
188 static bool DmaRxDoneCallback(gdma_channel_handle_t dma_chan,
189 gdma_event_data_t* event_data,
void* user_data);
194 static bool DmaRxDescrErrCallback(gdma_channel_handle_t dma_chan,
195 gdma_event_data_t* event_data,
void* user_data);
216 void ConfigureRxInterruptPath();
218#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
232 void HandleDmaRxDone(gdma_event_data_t* event_data,
bool in_isr);
237 void HandleDmaRxError(
bool in_isr);
240 void StopDmaRx(
bool in_isr);
242 void ResetDmaRxDescriptors(
bool in_isr);
244 void StartDmaRx(
bool in_isr);
250 void HandleDmaTxError(
bool in_isr);
263 bool LoadActiveTxFromQueue(
bool in_isr);
269 bool LoadPendingTxFromQueue(
bool in_isr);
274 bool PromotePendingTxToActive();
279 bool StartActiveTransfer(
bool in_isr);
284 bool StartAndReportActive(
bool in_isr);
289 void ClearActiveTx();
295 void FillTxFifo(
bool in_isr);
300 void PushRxBytes(
const uint8_t* data,
size_t size,
bool in_isr);
306 void DrainRxFifo(
bool in_isr);
311 void HandleUartInterrupt();
314 void EnableUartInterrupt(uint32_t mask);
316 void DisableUartInterrupt(uint32_t mask);
318 void ClearUartInterrupt(uint32_t mask);
320 void DisableAndClearUartInterrupt(uint32_t mask);
322 uint32_t CaptureUartInterrupt(uint32_t mask);
328 void OnTxTransferDone(
bool in_isr,
ErrorCode result);
330 static constexpr uint32_t EVENT_WRITE = 1U << 0U;
331 static constexpr uint32_t EVENT_TX_DONE = 1U << 1U;
332 static constexpr uint32_t EVENT_RX_WORK = 1U << 2U;
333 static constexpr uint32_t EVENT_CONFIG = 1U << 3U;
334 static constexpr uint32_t EVENT_TX_WORK = 1U << 4U;
335 static constexpr uint32_t EVENT_TX_ERROR = 1U << 5U;
336 static constexpr uint32_t EVENT_RX_ERROR = 1U << 6U;
338 enum class ConfigState : uint8_t
346 void ServiceEvents(uint32_t events,
bool in_isr);
348 ErrorCode ApplyConfig(
const UART::Configuration& config);
350 bool TryApplyPublishedConfig(
bool in_isr);
352 uart_port_t uart_num_;
358 UART::Configuration config_;
359 uint32_t uart_sclk_hz_ = 0U;
361 uint8_t* rx_isr_buffer_ =
nullptr;
362 size_t rx_isr_buffer_size_ = 0;
364 uint8_t* tx_storage_ =
nullptr;
365 DoubleBuffer tx_dma_buffer_{};
366 size_t tx_active_length_ = 0U;
367 bool tx_active_valid_ =
false;
368 Flag::Plain tx_busy_;
370 bool uart_hw_enabled_ =
false;
371 uart_hal_context_t uart_hal_ = {};
372 intr_handle_t uart_intr_handle_ =
nullptr;
373 bool uart_isr_installed_ =
false;
374 bool dma_requested_ =
true;
377 SerializedService service_{};
379 UART::Configuration requested_config_{};
381 std::atomic<uint8_t> config_state_{
static_cast<uint8_t
>(ConfigState::EMPTY)};
383 DECLARE_CRIT_SECTION_LOCK_IN_STRUCT(irq_lock_)
385 ESP32UARTReadPort _read_port;
386 WritePort _write_port;
388#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
389 bool dma_backend_enabled_ =
false;
390 uhci_hal_context_t uhci_hal_ = {};
391 gdma_channel_handle_t tx_dma_channel_ =
nullptr;
392 gdma_channel_handle_t rx_dma_channel_ =
nullptr;
393 uintptr_t tx_dma_head_addr_[2] = {0U, 0U};
394 gdma_link_list_handle_t rx_dma_link_ =
nullptr;
395 uint8_t* rx_dma_storage_ =
nullptr;
396 size_t rx_dma_chunk_size_ = 0;
397 uint32_t rx_dma_node_index_ = 0;
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.