libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
ep_pool.cpp
1#include "ep_pool.hpp"
2
3using namespace LibXR::USB;
4
5EndpointPool::EndpointPool(size_t endpoint_num) { ASSERT(endpoint_num >= 2); }
6
8{
9 if (ep == nullptr)
10 {
12 }
13
14 const auto ep_num = static_cast<size_t>(ep->GetNumber());
15 if (ep_num >= SLOT_COUNT)
16 {
18 }
19
21
22 // BOTH 端点同时登记到该号的两个方向槽;其余按具体方向入位。
23 // A BOTH endpoint is registered into both direction slots of its number; others go
24 // into their concrete direction slot.
26 {
27 for (size_t d = 0; d < DIR_COUNT; ++d)
28 {
29 if (slots_[ep_num][d] != nullptr)
30 {
32 }
33 }
34 for (size_t d = 0; d < DIR_COUNT; ++d)
35 {
36 slots_[ep_num][d] = ep;
37 use_[ep_num][d] = SlotUse::AVAILABLE;
38 }
40 }
41
42 const size_t d = DirIndex(dir);
43 if (slots_[ep_num][d] != nullptr)
44 {
46 }
47 slots_[ep_num][d] = ep;
48 use_[ep_num][d] = SlotUse::AVAILABLE;
50}
51
53 Endpoint::EPNumber ep_num)
54{
55 const auto num = static_cast<size_t>(ep_num);
56 if (num >= SLOT_COUNT || direction == Endpoint::Direction::BOTH)
57 {
59 }
60
61 const size_t d = DirIndex(direction);
62 Endpoint* ep = slots_[num][d];
63 if (ep == nullptr || use_[num][d] != SlotUse::AVAILABLE)
64 {
66 }
67
68 // 端点登记方向必须与请求方向兼容(具体方向匹配,或登记为 BOTH)。
69 // The registered direction must be compatible with the requested one (exact match, or
70 // registered as BOTH).
71 const Endpoint::Direction avail = ep->AvailableDirection();
72 if (avail != direction && avail != Endpoint::Direction::BOTH)
73 {
75 }
76
77 ep_info = ep;
78
79 // BOTH 端点占用后,两个方向槽一并标记为使用中。
80 // For a BOTH endpoint, mark both direction slots as in-use together.
81 if (avail == Endpoint::Direction::BOTH)
82 {
83 use_[num][0] = SlotUse::IN_USE;
84 use_[num][1] = SlotUse::IN_USE;
85 }
86 else
87 {
88 use_[num][d] = SlotUse::IN_USE;
89 }
91}
92
94{
95 if (ep_info == nullptr)
96 {
98 }
99
100 const auto num = static_cast<size_t>(ep_info->GetNumber());
101 if (num >= SLOT_COUNT)
102 {
104 }
105
106 bool released = false;
107 for (size_t d = 0; d < DIR_COUNT; ++d)
108 {
109 if (slots_[num][d] == ep_info && use_[num][d] == SlotUse::IN_USE)
110 {
111 use_[num][d] = SlotUse::AVAILABLE;
112 released = true;
113 }
114 }
115
117}
118
120{
121 const Endpoint::Direction direction =
123
124 if ((ep_addr & 0x7F) == 0)
125 {
126 ans = (direction == Endpoint::Direction::IN) ? ep0_in_ : ep0_out_;
127 return (ans != nullptr) ? LibXR::ErrorCode::OK : LibXR::ErrorCode::NOT_FOUND;
128 }
129
130 const size_t num = ep_addr & 0x7F;
131 if (num >= SLOT_COUNT)
132 {
134 }
135
136 const size_t d = DirIndex(direction);
137 Endpoint* ep = slots_[num][d];
138 // 仅「已分配(in-use)」且当前配置地址/方向与请求一致的端点可被反查到。
139 // 必须核对 GetAddress()/GetDirection()(当前配置方向):
140 // 一个 BOTH 端点被配置成单一方向后,不会再被另一方向的同号地址查到。
141 // Only endpoints that are allocated (in-use) AND whose current configured
142 // address/direction match the request are visible here.
143 // GetAddress()/GetDirection() (the configured direction) are checked so that once a
144 // BOTH endpoint is configured for a single direction, it is no longer reachable via the
145 // opposite-direction address of the same number.
146 if (ep != nullptr && use_[num][d] == SlotUse::IN_USE && ep->GetAddress() == ep_addr &&
147 ep->GetDirection() == direction)
148 {
149 ans = ep;
151 }
152
154}
155
157
159
161{
162 ep0_in_ = ep0_in;
163 ep0_out_ = ep0_out;
164}
USB 端点基类 / USB Endpoint base class.
Definition ep.hpp:24
EPNumber
端点号 Endpoint number
Definition ep.hpp:42
Direction AvailableDirection() const
获取允许配置的方向 / Get allowed endpoint direction
Definition ep.hpp:175
uint8_t GetAddress() const
获取端点地址(方向 + 号) / Get endpoint address (dir + num)
Definition ep.hpp:194
Direction
端点方向 Endpoint direction
Definition ep.hpp:31
@ BOTH
双向(可配置为 IN/OUT) / Both (configurable as IN/OUT)
@ IN
输入方向 / IN direction
@ OUT
输出方向 / OUT direction
Direction GetDirection() const
获取当前端点方向 / Get current endpoint direction
Definition ep.hpp:181
EPNumber GetNumber() const
获取端点号 / Get endpoint number
Definition ep.hpp:169
EndpointPool(size_t endpoint_num)
构造函数 / Constructor
Definition ep_pool.cpp:5
ErrorCode Put(Endpoint *ep)
登记一个端点到池中 / Register an endpoint into the pool
Definition ep_pool.cpp:7
Endpoint * GetEndpoint0In()
获取端点0的IN对象 / Get Endpoint 0's IN object
Definition ep_pool.cpp:158
void SetEndpoint0(Endpoint *ep0_in, Endpoint *ep0_out)
设置端点0的IN/OUT对象 / Set Endpoint 0 IN/OUT objects
Definition ep_pool.cpp:160
ErrorCode Release(Endpoint *ep_info)
回收端点 / Release endpoint
Definition ep_pool.cpp:93
ErrorCode FindEndpoint(uint8_t ep_addr, Endpoint *&ans)
查找端点/ Lookup endpoint
Definition ep_pool.cpp:119
Endpoint * GetEndpoint0Out()
获取端点0的OUT对象 / Get Endpoint 0's OUT object
Definition ep_pool.cpp:156
ErrorCode Get(Endpoint *&ep_info, Endpoint::Direction direction, Endpoint::EPNumber ep_num)
分配端点 / Allocate endpoint
Definition ep_pool.cpp:52
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ NOT_FOUND
未找到 / Not found
@ FULL
已满 / Full
@ OK
操作成功 / Operation successful
@ ARG_ERR
参数错误 / Argument error