6#include "libxr_def.hpp"
65 const std::size_t REMAINING =
Remaining();
72 const std::size_t TAKE = (REMAINING < cap) ? REMAINING : cap;
111 auto ans =
port_.queue_info_->Pop(popped);
116 *completed_info = popped;
225 using LibXR::UART::Read;
227 using LibXR::UART::Write;
242 size_t rx_buffer_size = 128,
size_t tx_buffer_size = 128,
size_t tx_queue_size = 5,
246 const char* control_interface_string = CDCBase::DEFAULT_CONTROL_INTERFACE_STRING,
247 const char* data_interface_string = CDCBase::DEFAULT_DATA_INTERFACE_STRING)
248 :
CDCBase(data_in_ep_num, data_out_ep_num, comm_ep_num, control_interface_string,
249 data_interface_string),
268 auto& line_coding = GetLineCoding();
273 line_coding.bCharFormat = 0;
276 line_coding.bCharFormat = 2;
285 line_coding.bParityType = 0;
288 line_coding.bParityType = 1;
291 line_coding.bParityType = 2;
304 line_coding.bDataBits =
static_cast<uint8_t
>(cfg.
data_bits);
310 line_coding.dwDTERate = cfg.
baudrate;
326 auto ep_data_out = GetDataOutEndpoint();
327 if (ep_data_out ==
nullptr)
332 const std::size_t MPS = ep_data_out->MaxPacketSize();
365 auto ans = ep_data_out->Transfer(MPS);
433 if (cdc->in_write_isr_.IsSet())
438 auto ep = cdc->GetDataInEndpoint();
447 auto pop_ans = port.queue_info_->Pop(info);
453 auto drop_ans = port.queue_data_->
PopBatch(
nullptr, info.data.size_);
466 if (ep->GetActiveLength() != 0)
476 if (cdc->tx_deq_.HasOp())
478 cdc->need_write_zlp_ =
false;
489 auto buffer = ep->GetBuffer();
493 cdc->tx_deq_.Take(
reinterpret_cast<uint8_t*
>(buffer.addr_), buffer.size_, len);
503 ep->SetActiveLength(len);
506 std::atomic_signal_fence(std::memory_order_seq_cst);
512 const std::size_t TO_SEND = ep->GetActiveLength();
524 !cdc->tx_deq_.HasOp())
529 std::atomic_signal_fence(std::memory_order_seq_cst);
532 ep->SetActiveLength(0);
533 auto ans = ep->Transfer(TO_SEND);
542 if (slot_ec ==
ErrorCode::OK && cdc->tx_deq_.HeadCompleted())
544 auto pop_ok = cdc->tx_deq_.PopCompleted(
nullptr);
549 const std::size_t MPS = ep->MaxPacketSize();
550 if (MPS > 0 && (TO_SEND % MPS) == 0 && ep->GetActiveLength() == 0 &&
551 !cdc->tx_deq_.HasOp())
553 cdc->need_write_zlp_ =
true;
561 if (!cdc->tx_deq_.HasOp())
566 auto buffer = ep->GetBuffer();
567 std::size_t len2 = 0;
570 cdc->tx_deq_.Take(
reinterpret_cast<uint8_t*
>(buffer.addr_), buffer.size_, len2);
580 ep->SetActiveLength(len2);
600 reinterpret_cast<const uint8_t*
>(data.
addr_), data.
size_);
629 auto ep = GetDataInEndpoint();
655 auto z = ep->TransferZLP();
665 const std::size_t PENDING_LEN = ep->GetActiveLength();
666 if (PENDING_LEN == 0)
673 ep->SetActiveLength(0);
674 auto ans = ep->Transfer(PENDING_LEN);
692 auto buffer = ep->GetBuffer();
693 std::size_t len2 = 0;
696 tx_deq_.
Take(
reinterpret_cast<uint8_t*
>(buffer.addr_), buffer.size_, len2);
699 ep->SetActiveLength(len2);
705 const std::size_t MPS = ep->MaxPacketSize();
706 if (!primed && PENDING_LEN > 0 && MPS > 0 && (PENDING_LEN % MPS) == 0 &&
WritePort(info 队列 + data 队列)的“单 op 不跨界”出队辅助器 Dequeue helper for WritePort (info + data) without cross...
WritePort & port_
写端口引用 / Write port reference
bool HeadCompleted() const
head op 是否已全部出队 Whether the cached head op is fully dequeued
CDCUartTxOpDequeueHelper(WritePort &port)
构造函数 Constructor
bool head_valid_
head 缓存有效标志 / Cached head valid flag
void Reset()
重置内部状态(head 缓存与偏移) Reset internal state (cached head and offset)
ErrorCode EnsureHead()
确保 head 缓存可用(必要时 Peek info) Ensure cached head is valid (Peek info if needed)
WriteInfoBlock head_
缓存的 head info / Cached head info
ErrorCode PopCompleted(WriteInfoBlock *completed_info=nullptr)
在 head 完成后 pop info 并重置状态 Pop info after head completes and reset state
bool HasOp()
是否存在可处理的 op Whether any op exists
std::size_t offset_
当前 op 已出队偏移 / Dequeued offset within current op
std::size_t Remaining() const
当前 op 剩余未出队字节数 Remaining bytes of current op
ErrorCode Take(uint8_t *dst, std::size_t cap, std::size_t &out_len)
从 data 队列搬运数据到目标 buffer,并推进 offset(不 pop info) Dequeue bytes from data queue into destination buffer ...
常量原始数据封装类。 A class for encapsulating constant raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
const void * addr_
数据存储地址(常量)。 The storage address of the data (constant).
普通标志位(非原子)/ Non-atomic flag
作用域标志管理器:构造时写入指定值,析构时恢复原值 / Scoped flag restorer: set on entry, restore on exit
void Reset()
重置队列 / Resets the queue
ErrorCode PushBatch(const Data *data, size_t size)
批量推入数据 / Pushes multiple elements into the queue
size_t EmptySize()
计算队列剩余可用空间 / Calculates the remaining available space in the queue
size_t Size() const
获取当前队列中的元素数量 / Returns the number of elements currently in the queue
ErrorCode PopBatch(Data *data, size_t size)
批量弹出数据 / Pops multiple elements from the queue
ReadPort class for handling read operations.
void ProcessPendingReads(bool in_isr)
Processes pending reads.
ReadPort & operator=(ReadFun fun)
赋值运算符重载,用于设置读取函数。 Overloaded assignment operator to set the read function.
通用异步收发传输(UART)基类 / Abstract base class for Universal Asynchronous Receiver-Transmitter (UART)
ReadPort * read_port_
读取端口 / Read port
@ NO_PARITY
无校验 / No parity
WritePort * write_port_
写入端口 / Write port
USB CDC ACM (Abstract Control Model) 设备类实现 USB CDC ACM (Abstract Control Model) device class implemen...
ErrorCode SendSerialState()
发送串行状态通知 Send serial state notification
virtual void UnbindEndpoints(EndpointPool &endpoint_pool, bool) override
反初始化CDC设备 Deinitialize CDC device
USB CDC-ACM UART 适配器 USB CDC-ACM UART adapter.
CDCUartReadPort read_port_cdc_
CDC RX 读端口 / CDC RX read port.
CDCUart(size_t rx_buffer_size=128, size_t tx_buffer_size=128, size_t tx_queue_size=5, Endpoint::EPNumber data_in_ep_num=Endpoint::EPNumber::EP_AUTO, Endpoint::EPNumber data_out_ep_num=Endpoint::EPNumber::EP_AUTO, Endpoint::EPNumber comm_ep_num=Endpoint::EPNumber::EP_AUTO, const char *control_interface_string=CDCBase::DEFAULT_CONTROL_INTERFACE_STRING, const char *data_interface_string=CDCBase::DEFAULT_DATA_INTERFACE_STRING)
构造函数 Constructor
bool TryRearmOut(bool in_isr)
尝试 rearm OUT(背压恢复/持续接收) Try to rearm OUT endpoint (backpressure recovery / continuous RX)
void UnbindEndpoints(EndpointPool &endpoint_pool, bool in_isr) override
解绑端点(清理队列、状态与背压标志) Unbind endpoints (cleanup queues, states, and backpressure flags)
static ErrorCode WriteFun(WritePort &port, bool in_isr)
写端口回调(TX) Write port callback (TX)
void OnDataInComplete(bool in_isr, ConstRawData &data) override
IN 完成回调(TX) IN complete callback (TX)
LibXR::CDCUartTxOpDequeueHelper tx_deq_
TX 出队辅助器 / TX dequeue helper.
void OnDataOutComplete(bool in_isr, ConstRawData &data) override
OUT 完成回调(RX) OUT complete callback (RX)
bool need_write_zlp_
ZLP 需求标志 / ZLP required flag.
LibXR::WritePort write_port_cdc_
CDC TX 写端口 / CDC TX write port.
ErrorCode SetConfig(UART::Configuration cfg) override
设置 UART 配置(CDC Line Coding) Set UART configuration (CDC Line Coding)
Flag::Plain in_write_isr_
写 ISR 保护标志 / Write ISR guard flag
CDC UART 读端口(背压 + pending 缓存) CDC UART read port (backpressure + pending cache)
CDCUartReadPort(uint32_t size, CDCUart &owner)
构造函数 Constructor
ConstRawData pending_data_
pending 数据(指向底层 USB buffer)/ Pending data pointing to USB buffer
CDCUart & owner_
所属 CDCUart / Owning CDCUart
bool recv_pause_
背压标志:true 表示 OUT 未 rearm / Backpressure flag: OUT not rearmed
void OnRxDequeue(bool in_isr) override
数据队列被消费时回调(解除背压并尝试恢复 OUT rearm) Called when RX queue is dequeued (lift backpressure and try to rearm ...
EPNumber
端点号 Endpoint number
@ EP_AUTO
自动分配端点号 / Auto allocate
USB端点池类 / USB endpoint pool class.
WritePort class for handling write operations.
void Finish(bool in_isr, ErrorCode ans, WriteInfoBlock &info)
更新写入操作的状态。 Updates the status of the write operation.
void Reset()
Resets the WritePort.
@ INIT_ERR
初始化错误 | Initialization error
@ FAILED
操作失败 | Operation failed
@ OK
操作成功 | Operation successful
@ ARG_ERR
参数错误 | Argument error
ErrorCode(* ReadFun)(ReadPort &port, bool in_isr)
Function pointer type for read operations.
ErrorCode(* WriteFun)(WritePort &port, bool in_isr)
Function pointer type for write operations.
OwnerType * ContainerOf(MemberType *ptr, MemberType OwnerType::*member) noexcept
通过成员指针恢复其所属对象指针
UART 配置结构体 / UART configuration structure.
uint8_t stop_bits
停止位长度 / Number of stop bits
Parity parity
校验模式 / Parity mode
uint8_t data_bits
数据位长度 / Number of data bits
uint32_t baudrate
波特率 / Baud rate
ConstRawData data
Data buffer. 数据缓冲区。