5#include "soc/uart_periph.h"
9constexpr uint32_t kUartRxIntrMask =
10 UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_OVF;
11constexpr uint32_t kUartTxIntrMask = UART_INTR_TXFIFO_EMPTY;
17void IRAM_ATTR ESP32UART::UartIsrEntry(
void* arg)
19 auto* self =
static_cast<ESP32UART*
>(arg);
22 self->HandleUartInterrupt();
28 if (uart_isr_installed_)
33#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3
36 constexpr int kUartIntrFlags = 0;
38 constexpr int kUartIntrFlags = ESP_INTR_FLAG_IRAM;
41 const esp_err_t err = esp_intr_alloc(uart_periph_signal[uart_num_].irq, kUartIntrFlags,
42 UartIsrEntry,
this, &uart_intr_handle_);
48 uart_isr_installed_ =
true;
52void IRAM_ATTR ESP32UART::FillTxFifo(
bool in_isr)
54 if (!tx_active_valid_)
59#if SOC_GDMA_SUPPORTED && SOC_UHCI_SUPPORTED
60 if (dma_backend_enabled_)
62 while (tx_active_offset_ < tx_active_length_)
64 if (uart_hal_get_txfifo_len(&uart_hal_) == 0)
69 uint32_t write_size = 0;
70 const uint8_t* src = tx_active_buffer_ + tx_active_offset_;
71 const uint32_t remaining =
72 static_cast<uint32_t
>(tx_active_length_ - tx_active_offset_);
74 uart_hal_write_txfifo(&uart_hal_, src, remaining, &write_size);
80 tx_active_offset_ += write_size;
86 while (tx_active_offset_ < tx_active_length_)
88 const uint32_t fifo_space = uart_hal_get_txfifo_len(&uart_hal_);
94 const size_t remaining = tx_active_length_ - tx_active_offset_;
95 const size_t chunk_size = std::min<size_t>(remaining, fifo_space);
99 [
this](
const uint8_t* src,
size_t size) ->
ErrorCode
101 uint32_t write_size = 0;
102 uart_hal_write_txfifo(&uart_hal_, src,
static_cast<uint32_t
>(size),
104 return (write_size ==
static_cast<uint32_t
>(size)) ?
ErrorCode::OK
113 tx_active_offset_ += chunk_size;
117 if ((tx_active_offset_ < tx_active_length_) || !in_isr)
122 uart_hal_disable_intr_mask(&uart_hal_, UART_INTR_TXFIFO_EMPTY);
126void IRAM_ATTR ESP32UART::DrainRxFifoFromIsr()
128 bool pushed_any =
false;
129 while (uart_hal_get_rxfifo_len(&uart_hal_) > 0U)
131 const size_t fifo_len = uart_hal_get_rxfifo_len(&uart_hal_);
140 [
this](uint8_t* buffer,
size_t chunk_size) ->
ErrorCode
142 int read_len =
static_cast<int>(chunk_size);
143 uart_hal_read_rxfifo(&uart_hal_, buffer, &read_len);
144 return (read_len ==
static_cast<int>(chunk_size)) ?
ErrorCode::OK
167void IRAM_ATTR ESP32UART::HandleRxInterrupt(uint32_t uart_intr_status)
169 const bool has_overflow = (uart_intr_status & UART_INTR_RXFIFO_OVF) != 0U;
170 const bool has_rx_data =
171 (uart_intr_status & (UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT)) != 0U;
173 if (!has_overflow && !has_rx_data)
182 uart_hal_clr_intsts_mask(&uart_hal_, UART_INTR_RXFIFO_OVF);
185 DrainRxFifoFromIsr();
186 uart_hal_clr_intsts_mask(&uart_hal_, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT);
189void IRAM_ATTR ESP32UART::HandleTxInterrupt(uint32_t uart_intr_status)
191 if ((uart_intr_status & UART_INTR_TXFIFO_EMPTY) == 0U)
196 Flag::ScopedRestore tx_flag(in_tx_isr_);
198 uart_hal_clr_intsts_mask(&uart_hal_, UART_INTR_TXFIFO_EMPTY);
201void IRAM_ATTR ESP32UART::HandleUartInterrupt()
203 uint32_t uart_intr_status = uart_hal_get_intsts_mask(&uart_hal_);
205 while (uart_intr_status != 0)
207 if (uart_intr_status & kUartRxIntrMask)
209 HandleRxInterrupt(uart_intr_status);
212 if (uart_intr_status & kUartTxIntrMask)
214 HandleTxInterrupt(uart_intr_status);
217 uart_intr_status = uart_hal_get_intsts_mask(&uart_hal_);
size_t EmptySize()
计算队列剩余可用空间 / Calculates the remaining available space in the queue
ErrorCode PushWithWriter(size_t size, Writer &&writer)
通过写入器回调写入固定长度数据(单生产者) / Push fixed-size data via writer callback (single producer)
ErrorCode PopWithReader(size_t size, Reader &&reader)
通过读取器回调弹出固定长度数据(单消费者) / Pop fixed-size data via reader callback (single consumer)
void ProcessPendingReads(bool in_isr)
Processes pending reads.
ReadPort * read_port_
读取端口 / Read port
WritePort * write_port_
写入端口 / Write port
@ INIT_ERR
初始化错误 | Initialization error
@ OK
操作成功 | Operation successful