libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
esp_uart.hpp
1#pragma once
2
3#include <atomic>
4#include <cstddef>
5#include <cstdint>
6
7#include "driver/gpio.h"
8#include "esp_def.hpp"
9#include "esp_idf_version.h"
10#include "esp_intr_alloc.h"
11#include "flag.hpp"
12#include "hal/uart_hal.h"
13#include "hal/uart_types.h"
14#include "latest_snapshot.hpp"
15#include "model/uart_dma_tx_model.hpp"
16#include "model/uart_rx_config_gate.hpp"
17#include "soc/periph_defs.h"
18#include "soc/soc_caps.h"
19#include "uart.hpp"
20
21#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
22#include "esp_private/gdma.h"
23#include "esp_private/gdma_link.h"
24#include "hal/uhci_hal.h"
25#endif
26
27namespace LibXR
28{
29
30class ESP32UART;
31
41{
42 public:
49 explicit ESP32UARTReadPort(size_t size, ESP32UART& owner)
50 : ReadPort(size), owner_(owner)
51 {
52 }
53
57 void OnRxDequeue(bool in_isr) override;
58
59 ESP32UARTReadPort& operator=(ReadFun fun)
60 {
62 return *this;
63 }
64
65 private:
67};
68
78class ESP32UART : public UART
79{
80 friend class ESP32UARTReadPort;
81 friend class UartDmaTxModel<ESP32UART>;
82
83 public:
84 static constexpr int PIN_NO_CHANGE = -1;
85
90 ESP32UART(uart_port_t uart_num, int tx_pin, int rx_pin, int rts_pin = PIN_NO_CHANGE,
91 int cts_pin = PIN_NO_CHANGE, size_t rx_buffer_size = 1024,
92 size_t tx_buffer_size = 512, uint32_t tx_queue_size = 5,
93 UART::Configuration config = {115200, UART::Parity::NO_PARITY, 8, 1},
94 bool enable_dma = true);
95
100 ErrorCode SetConfig(UART::Configuration config) override;
101
106 ErrorCode SetLoopback(bool enable);
107
112 static ErrorCode WriteFun(WritePort& port, bool in_isr);
113
118 static ErrorCode ReadFun(ReadPort& port, bool in_isr);
119
120 private:
125 static uint8_t* AllocateTxStorage(size_t size);
126
131 static ErrorCode ResolveUartPeriph(uart_port_t uart_num, periph_module_t& out);
132
137 static bool ResolveWordLength(uint8_t data_bits, uart_word_length_t& out);
138
143 static bool ResolveStopBits(uint8_t stop_bits, uart_stop_bits_t& out);
144
149 static uart_parity_t ResolveParity(UART::Parity parity);
150
151 void OnConfigRequested();
152 bool ApplyPendingConfig(bool in_isr);
153 bool OnConfigApplied(bool in_isr);
154
159 static void UartIsrEntry(void* arg);
160
161#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
166 static bool DmaTxEofCallback(gdma_channel_handle_t dma_chan,
167 gdma_event_data_t* event_data, void* user_data);
168
173 static bool DmaTxDescrErrCallback(gdma_channel_handle_t dma_chan,
174 gdma_event_data_t* event_data, void* user_data);
175
180 static bool DmaRxDoneCallback(gdma_channel_handle_t dma_chan,
181 gdma_event_data_t* event_data, void* user_data);
182
187 static bool DmaRxDescrErrCallback(gdma_channel_handle_t dma_chan,
188 gdma_event_data_t* event_data, void* user_data);
189#endif
190
196
202
208
214
215 bool StartDmaTx(uint8_t* data, size_t size, int block);
216
217#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
222 ErrorCode InitDmaBackend();
223
235 void HandleDmaRxDone(gdma_event_data_t* event_data);
236
241 void HandleDmaRxError();
242
247 void HandleDmaTxError();
248
253 void PushDmaRxData(size_t recv_size, bool in_isr);
254#endif
255
260 ErrorCode TryStartTx(bool in_isr);
261
266 bool LoadActiveTxFromQueue(bool in_isr);
267
272 bool DequeueFifoTx(size_t& size, WriteInfoBlock& info);
273
278 bool StartActiveTransfer(bool in_isr);
279
284 bool StartAndReportActive(bool in_isr);
285
290 void ClearActiveTx();
291
296 void FillTxFifo(bool in_isr);
297
302 void PushRxBytes(const uint8_t* data, size_t size, bool in_isr);
303
308 void DrainRxFifo(bool in_isr);
309
314 void HandleRxInterrupt(uint32_t uart_intr_status);
315
320 void HandleTxInterrupt(uint32_t uart_intr_status);
321
326 void HandleUartInterrupt();
327
332 void OnTxTransferDone(bool in_isr, ErrorCode result);
333
334 uart_port_t uart_num_;
339
341 LatestSnapshot<UART::Configuration> requested_config_;
342 UartRxConfigGate rx_config_gate_;
343
344 uint8_t* rx_isr_buffer_ = nullptr;
346
347 uint8_t* tx_storage_ = nullptr;
349 size_t tx_active_length_ = 0U;
350 size_t tx_active_offset_ = 0U;
351 bool tx_active_valid_ = false;
354
355 bool uart_hw_enabled_ = false;
356 uart_hal_context_t uart_hal_ = {};
357 intr_handle_t uart_intr_handle_ = nullptr;
358 bool uart_isr_installed_ = false;
359 bool dma_requested_ = true;
360
364
365#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
366 bool dma_backend_enabled_ = false;
367 uhci_hal_context_t uhci_hal_ = {};
368 gdma_channel_handle_t tx_dma_channel_ = nullptr;
369 gdma_channel_handle_t rx_dma_channel_ = nullptr;
370 uintptr_t tx_dma_head_addr_[2] = {0U, 0U};
371 gdma_link_list_handle_t rx_dma_link_ = nullptr;
372 uint8_t* rx_dma_storage_ = nullptr;
373 size_t rx_dma_chunk_size_ = 0;
374 uint32_t rx_dma_node_index_ = 0;
375#endif
376};
377
378} // namespace LibXR
ESP32 UART backend with FIFO and optional GDMA fast paths.
Definition esp_uart.hpp:79
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 TryStartTx(bool in_isr)
Try to start queued transmit work.
Definition esp_uart.cpp:544
ErrorCode SetConfig(UART::Configuration config) override
Apply a new UART framing and baud configuration.
Definition esp_uart.cpp:185
UART::Configuration config_
Current UART framing configuration.
Definition esp_uart.hpp:340
ErrorCode SetLoopback(bool enable)
Toggle UART peripheral internal loopback mode.
Definition esp_uart.cpp:317
void HandleUartInterrupt()
Dispatch pending UART interrupt reasons.
int rx_pin_
RX GPIO pin or PIN_NO_CHANGE.
Definition esp_uart.hpp:336
int tx_pin_
TX GPIO pin or PIN_NO_CHANGE.
Definition esp_uart.hpp:335
bool LoadActiveTxFromQueue(bool in_isr)
Load one active TX request from the queue.
Definition esp_uart.cpp:574
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:359
intr_handle_t uart_intr_handle_
Registered UART interrupt handle.
Definition esp_uart.hpp:357
Flag::Plain tx_busy_
Hardware TX engine currently owns the request.
Definition esp_uart.hpp:352
bool StartActiveTransfer(bool in_isr)
Start the active request on the selected TX backend.
Definition esp_uart.cpp:626
uint8_t * rx_isr_buffer_
Scratch buffer used by the RX ISR path.
Definition esp_uart.hpp:344
uart_hal_context_t uart_hal_
ESP-IDF UART HAL context.
Definition esp_uart.hpp:356
uint8_t * tx_storage_
Backing storage for the TX half-buffers.
Definition esp_uart.hpp:347
bool DequeueFifoTx(size_t &size, WriteInfoBlock &info)
Claim one queued request for the FIFO TX backend.
Definition esp_uart.cpp:596
ErrorCode InitUartHardware()
Initialize UART hardware and base HAL state.
Definition esp_uart.cpp:411
static uart_parity_t ResolveParity(UART::Parity parity)
Convert configured parity into the HAL enum.
Definition esp_uart.cpp:393
size_t rx_isr_buffer_size_
Size of rx_isr_buffer_.
Definition esp_uart.hpp:345
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.
Definition esp_uart.cpp:104
bool tx_active_valid_
Whether the active TX metadata is valid.
Definition esp_uart.hpp:351
void OnTxTransferDone(bool in_isr, ErrorCode result)
Finalize one TX transfer result.
Definition esp_uart.cpp:686
WritePort _write_port
Write-side queue bridge exposed to UART.
Definition esp_uart.hpp:362
void DrainRxFifo(bool in_isr)
Drain pending bytes from the hardware RX FIFO.
WriteInfoBlock tx_active_info_
Metadata for the active TX request.
Definition esp_uart.hpp:348
void HandleTxInterrupt(uint32_t uart_intr_status)
Handle TX-side UART interrupt reasons.
int cts_pin_
CTS GPIO pin or PIN_NO_CHANGE.
Definition esp_uart.hpp:338
Flag::Plain in_tx_isr_
Reentry guard while processing TX ISR work.
Definition esp_uart.hpp:353
bool StartAndReportActive(bool in_isr)
Start the active request and report queue completion ownership.
Definition esp_uart.cpp:523
int rts_pin_
RTS GPIO pin or PIN_NO_CHANGE.
Definition esp_uart.hpp:337
void HandleRxInterrupt(uint32_t uart_intr_status)
Handle RX-side UART interrupt reasons.
ESP32UARTReadPort _read_port
Read-side queue bridge exposed to UART.
Definition esp_uart.hpp:361
bool uart_isr_installed_
UART ISR installation state.
Definition esp_uart.hpp:358
UartDmaTxModel< ESP32UART > tx_dma_model_
One-shot DMA TX execution model.
Definition esp_uart.hpp:363
void ClearActiveTx()
Clear active TX state.
Definition esp_uart.cpp:511
static uint8_t * AllocateTxStorage(size_t size)
Allocate DMA-capable backing storage for TX buffers.
Definition esp_uart.cpp:66
static bool ResolveStopBits(uint8_t stop_bits, uart_stop_bits_t &out)
Convert configured stop bits into the HAL enum.
Definition esp_uart.cpp:376
uart_port_t uart_num_
Selected UART peripheral index.
Definition esp_uart.hpp:334
size_t tx_active_offset_
Bytes already emitted for the active request.
Definition esp_uart.hpp:350
static bool ResolveWordLength(uint8_t data_bits, uart_word_length_t &out)
Convert configured data bits into the HAL enum.
Definition esp_uart.cpp:353
bool uart_hw_enabled_
UART hardware block was initialized.
Definition esp_uart.hpp:355
void PushRxBytes(const uint8_t *data, size_t size, bool in_isr)
Push RX bytes into the software queue.
Definition esp_uart.cpp:650
size_t tx_active_length_
Active TX payload length in bytes.
Definition esp_uart.hpp:349
static constexpr int PIN_NO_CHANGE
Sentinel for an unmapped GPIO.
Definition esp_uart.hpp:84
ErrorCode InstallUartIsr()
Install the UART interrupt handler.
ErrorCode ConfigurePins()
Configure the selected GPIO pins.
Definition esp_uart.cpp:459
static void UartIsrEntry(void *arg)
UART ISR trampoline.
ESP32 UART 读端口 / ESP32 UART read port.
Definition esp_uart.hpp:41
ESP32UART & owner_
所属 UART 后端 / Owning UART backend
Definition esp_uart.hpp:66
void OnRxDequeue(bool in_isr) override
软件队列出队后的回调 / Callback after software RX dequeue
Definition esp_uart.cpp:52
ESP32UARTReadPort(size_t size, ESP32UART &owner)
构造读端口 / Construct the read port
Definition esp_uart.hpp:49
普通标志位(非原子)/ Non-atomic flag
Definition flag.hpp:115
SPSC mailbox retaining only the latest fully published value.
ReadPort class for handling read operations.
Definition read_port.hpp:18
ReadPort & operator=(ReadFun fun)
赋值运算符重载,用于设置读取函数。 Overloaded assignment operator to set the read function.
Definition read_port.cpp:28
通用异步收发传输(UART)基类 / Abstract base class for Universal Asynchronous Receiver-Transmitter (UART)
Definition uart.hpp:19
Parity
奇偶校验模式 / Parity mode
Definition uart.hpp:29
@ NO_PARITY
无校验 / No parity
UART 单次 DMA 发送执行模型 / UART one-shot DMA TX execution model.
Serialize UART RX hardware callbacks against configuration / 串行化 UART RX 硬件回调与配置事务
WritePort class for handling write operations.
LibXR 命名空间
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举
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.
Definition uart.hpp:44