18 cdc->RequestTx(in_isr);
27void CDCUart::RequestTx(
bool in_isr)
29 tx_service_.
Invoke(1U, in_isr,
30 [
this](uint32_t,
bool owner_in_isr) { ServiceTx(owner_in_isr); });
33void CDCUart::ServiceTx(
bool in_isr)
35 auto* ep = GetDataInEndpoint();
43 if (ep->GetActiveLength() == 0U && write_port_cdc_.
Size() == 0U)
45 [[maybe_unused]]
const auto ans = ep->TransferZLP();
47 need_write_zlp_ =
false;
50 need_write_zlp_ =
false;
55void CDCUart::StartTxBuffer(Endpoint& ep, [[maybe_unused]]
bool in_isr)
57 const size_t LENGTH = ep.GetActiveLength();
58 DEV_ASSERT_FROM_CALLBACK(LENGTH != 0U, in_isr);
59 ep.SetActiveLength(0U);
60 [[maybe_unused]]
const auto ans = ep.Transfer(LENGTH);
62 const size_t MPS = ep.MaxPacketSize();
63 need_write_zlp_ = MPS != 0U && LENGTH % MPS == 0U;
66void CDCUart::FillTxBuffer(Endpoint& ep,
bool in_isr)
74 const auto buffer = ep.GetBuffer();
75 ASSERT(buffer.addr_ !=
nullptr && buffer.size_ != 0U);
77 queue.PopWithWriter(buffer.size_,
78 [buffer](
const uint8_t* first,
size_t first_size,
79 const uint8_t* second,
size_t second_size) ->
size_t
81 auto* dst = static_cast<uint8_t*>(buffer.addr_);
84 std::memcpy(dst, first, first_size);
86 if (second_size != 0U)
88 std::memcpy(dst + first_size, second, second_size);
90 return first_size + second_size;
92 DEV_ASSERT_FROM_CALLBACK(LENGTH != 0U && LENGTH <= UINT16_MAX, in_isr);
93 ep.SetActiveLength(
static_cast<uint16_t
>(LENGTH));
94 need_write_zlp_ =
false;
97 StartTxBuffer(ep, in_isr);
101void CDCUart::ProgressTx(
bool in_isr)
103 auto* ep = GetDataInEndpoint();
104 if (ep ==
nullptr || !Inited() || ep->GetState() != Endpoint::State::IDLE)
109 if (ep->GetActiveLength() != 0U)
111 StartTxBuffer(*ep, in_isr);
115 FillTxBuffer(*ep, in_isr);
118 if (ep->GetState() == Endpoint::State::BUSY && ep->UseDoubleBuffer() &&
119 ep->GetActiveLength() == 0U)
121 FillTxBuffer(*ep, in_isr);
只读原始数据视图 / Immutable raw data view
bool Invoke(uint32_t events, bool in_isr, Handler &&handler) noexcept
发布事件并尝试取得执行权 / Publish events and attempt to claim execution.
virtual void BindEndpoints(EndpointPool &endpoint_pool, uint8_t start_itf_num, bool) override
初始化CDC设备 Initialize CDC device
static void WriteFun(WritePort &port, bool in_isr)
发送队列写入门铃 / Transmit queue write doorbell
void BindEndpoints(EndpointPool &endpoint_pool, uint8_t start_itf_num, bool in_isr) override
绑定端点并恢复配置前已排队的发送 / Bind endpoints and resume queued writes
void OnDataInComplete(bool in_isr, ConstRawData &data) override
在 IN 完成后请求推进发送 / Request TX progress after IN completion
USB端点池类 / USB endpoint pool class.
基于 SPSC 字节队列的写端口 / Write endpoint backed by an SPSC byte queue.
WriteQueue GetWriteQueue(bool in_isr=false)
获取已提交队头的出队接口 / Obtain a consumer interface for the released front.
size_t Size() const
获取字节队列当前数据量 / Get current byte queue occupancy.
@ OK
操作成功 / Operation successful
OwnerType * ContainerOf(MemberType *ptr, MemberType OwnerType::*member) noexcept
通过成员指针恢复其所属对象指针 Recover the owning object pointer from a member pointer