libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
LibXR::STM32Endpoint Class Reference

STM32 USB 端点实现 / STM32 USB endpoint implementation. More...

#include <stm32_usb_ep.hpp>

Inheritance diagram for LibXR::STM32Endpoint:
[legend]
Collaboration diagram for LibXR::STM32Endpoint:
[legend]

Public Member Functions

void Configure (const Config &cfg) override
 配置端点协议参数 / Configure endpoint protocol parameters
 
void Close () override
 关闭端点 / Close endpoint
 
ErrorCode Transfer (size_t size) override
 启动一次传输 / Start a transfer
 
ErrorCode Stall () override
 置 STALL / Stall endpoint
 
ErrorCode ClearStall () override
 清除 STALL / Clear stall
 
size_t MaxTransferSize () const override
 返回当前最大可传输字节数 / Return maximum transferable size at this time
 
- Public Member Functions inherited from LibXR::USB::Endpoint
 Endpoint (EPNumber number, Direction dir, RawData buffer)
 构造函数 / Constructor
 
virtual ~Endpoint ()=default
 虚析构函数 / Virtual destructor
 
 Endpoint (const Endpoint &)=delete
 
Endpointoperator= (const Endpoint &)=delete
 
EPNumber GetNumber () const
 获取端点号 / Get endpoint number
 
Direction AvailableDirection () const
 获取允许配置的方向 / Get allowed endpoint direction
 
Direction GetDirection () const
 获取当前端点方向 / Get current endpoint direction
 
uint8_t GetAddress () const
 获取端点地址(方向 + 号) / Get endpoint address (dir + num)
 
State GetState () const
 获取端点状态 / Get endpoint state
 
void SetState (State state)
 设置端点状态 / Set endpoint state
 
Type GetType () const
 获取端点类型 / Get endpoint type
 
uint16_t MaxPacketSize () const
 获取最大包长 / Get max packet size
 
bool IsStalled () const
 是否处于 STALL 状态 / Whether endpoint is stalled
 
bool UseDoubleBuffer () const
 是否启用双缓冲 / Whether double buffer is enabled
 
RawData GetBuffer () const
 获取当前可用于传输的缓冲区 / Get current transfer buffer
 
void SetOnTransferCompleteCallback (Callback< ConstRawData & > cb)
 设置传输完成回调 / Set transfer complete callback
 
void SetActiveLength (uint16_t len)
 设置当前活动缓冲区有效长度 / Set active buffer valid length
 
size_t GetActiveLength ()
 获取当前活动缓冲区有效长度 / Get active buffer valid length
 
virtual ErrorCode TransferMultiBulk (RawData &data)
 Bulk 多包传输辅助接口 / Helper for multi-packet bulk transfer.
 
virtual ErrorCode TransferZLP ()
 发送/接收 ZLP(零长度包) / Transfer zero length packet (ZLP)
 
void OnTransferCompleteCallback (bool in_isr, size_t actual_transfer_size)
 由底层在传输完成时调用 / Called by low-level driver when transfer completes
 

Data Fields

PCD_HandleTypeDef * hpcd_
 
size_t last_transfer_size_ = 0
 
stm32_usb_dev_id_t id_
 

Additional Inherited Members

- Public Types inherited from LibXR::USB::Endpoint
enum class  Direction : uint8_t { OUT = 0 , IN = 1 , BOTH = 2 }
 端点方向 Endpoint direction More...
 
enum class  EPNumber : uint8_t {
  EP0 = 0 , EP1 = 1 , EP2 = 2 , EP3 = 3 ,
  EP4 = 4 , EP5 = 5 , EP6 = 6 , EP7 = 7 ,
  EP8 = 8 , EP9 = 9 , EP10 = 10 , EP11 = 11 ,
  EP12 = 12 , EP13 = 13 , EP14 = 14 , EP15 = 15 ,
  EP_MAX_NUM = 16 , EP_AUTO = 0xFE , EP_INVALID = 0xFF
}
 端点号 Endpoint number More...
 
enum class  Type : uint8_t { CONTROL = 0 , ISOCHRONOUS = 1 , BULK = 2 , INTERRUPT = 3 }
 端点类型 Endpoint type More...
 
enum class  State : uint8_t {
  DISABLED , IDLE , BUSY , STALLED ,
  ERROR
}
 端点状态 Endpoint state More...
 
- Static Public Member Functions inherited from LibXR::USB::Endpoint
static constexpr uint8_t EPNumberToInt8 (EPNumber ep)
 端点号转换为 uint8_t / Convert endpoint number to uint8_t
 
static constexpr uint8_t EPNumberToAddr (EPNumber ep, Direction dir)
 端点号转换为端点地址 / Convert endpoint number to endpoint address
 
static constexpr EPNumber AddrToEPNumber (uint8_t addr, Direction &dir)
 端点地址转换为端点号 / Convert endpoint address to endpoint number
 
static constexpr EPNumber NextEPNumber (EPNumber ep)
 获取下一个端点号 / Get the next endpoint number
 
- Protected Member Functions inherited from LibXR::USB::Endpoint
ConfigGetConfig ()
 获取当前配置引用 / Get endpoint config reference
 
virtual void SwitchBuffer ()
 切换双缓冲 / Switch double buffer
 
virtual void SetActiveBlock (bool active_block)
 设置当前活动缓冲块 / Set active buffer block
 

Detailed Description

STM32 USB 端点实现 / STM32 USB endpoint implementation.

Definition at line 17 of file stm32_usb_ep.hpp.

Member Function Documentation

◆ ClearStall()

ErrorCode STM32Endpoint::ClearStall ( )
overridevirtual

清除 STALL / Clear stall

Returns
ErrorCode 错误码 / Error code

Implements LibXR::USB::Endpoint.

Definition at line 281 of file stm32_usb_ep.cpp.

282{
283 if (GetState() != State::STALLED)
284 {
285 return ErrorCode::FAILED;
286 }
287
288 uint8_t addr = EPNumberToAddr(GetNumber(), GetDirection());
289
291 {
293 return ErrorCode::OK;
294 }
295
296 if (HAL_PCD_EP_ClrStall(hpcd_, addr) == HAL_OK)
297 {
299 return ErrorCode::OK;
300 }
301 else
302 {
304 return ErrorCode::FAILED;
305 }
306}
@ EP0
端点 0 / Endpoint 0
static constexpr uint8_t EPNumberToAddr(EPNumber ep, Direction dir)
端点号转换为端点地址 / Convert endpoint number to endpoint address
Definition ep.hpp:105
Direction GetDirection() const
获取当前端点方向 / Get current endpoint direction
Definition ep.hpp:182
EPNumber GetNumber() const
获取端点号 / Get endpoint number
Definition ep.hpp:170
@ STALLED
停止/挂起 / Stalled
void SetState(State state)
设置端点状态 / Set endpoint state
Definition ep.hpp:214
State GetState() const
获取端点状态 / Get endpoint state
Definition ep.hpp:208
@ FAILED
操作失败 | Operation failed
@ OK
操作成功 | Operation successful

◆ Close()

void STM32Endpoint::Close ( )
overridevirtual

关闭端点 / Close endpoint

Implements LibXR::USB::Endpoint.

Definition at line 176 of file stm32_usb_ep.cpp.

177{
178 uint8_t addr = EPNumberToAddr(GetNumber(), GetDirection());
179 HAL_PCD_EP_Close(hpcd_, addr);
181}
@ DISABLED
禁用 / Disabled

◆ Configure()

void STM32Endpoint::Configure ( const Config & cfg)
overridevirtual

配置端点协议参数 / Configure endpoint protocol parameters

Parameters
cfg配置参数 / Configuration parameters

Implements LibXR::USB::Endpoint.

Definition at line 66 of file stm32_usb_ep.cpp.

67{
68 ASSERT(cfg.direction == Direction::IN || cfg.direction == Direction::OUT);
69
70 uint8_t addr = EPNumberToAddr(GetNumber(), cfg.direction);
71 uint8_t type = static_cast<uint8_t>(cfg.type);
72 auto& ep_cfg = GetConfig();
73 size_t packet_size_limit = 0;
74
75 ep_cfg = cfg;
76
77 switch (cfg.type)
78 {
79 case Type::BULK:
80#if defined(PCD_SPEED_HIGH_IN_FULL)
81 if (hpcd_->Init.speed == PCD_SPEED_FULL ||
82 hpcd_->Init.speed == PCD_SPEED_HIGH_IN_FULL)
83#else
84 if (hpcd_->Init.speed == PCD_SPEED_FULL)
85#endif
86 {
87 packet_size_limit = 64;
88 }
89 else
90 {
91 packet_size_limit = 512;
92 }
93 break;
94 case Type::INTERRUPT:
95#if defined(PCD_SPEED_HIGH_IN_FULL)
96 if (hpcd_->Init.speed == PCD_SPEED_FULL ||
97 hpcd_->Init.speed == PCD_SPEED_HIGH_IN_FULL)
98#else
99 if (hpcd_->Init.speed == PCD_SPEED_FULL)
100#endif
101 {
102 packet_size_limit = 64;
103 }
104 else
105 {
106 packet_size_limit = 1024;
107 }
108 break;
110#if defined(PCD_SPEED_HIGH_IN_FULL)
111 if (hpcd_->Init.speed == PCD_SPEED_FULL ||
112 hpcd_->Init.speed == PCD_SPEED_HIGH_IN_FULL)
113#else
114 if (hpcd_->Init.speed == PCD_SPEED_FULL)
115#endif
116 {
117 packet_size_limit = 1023;
118 }
119 else
120 {
121 packet_size_limit = 1024;
122 }
123 break;
124 case Type::CONTROL:
125 packet_size_limit = 64;
126 break;
127 default:
128 break;
129 }
130
131#if defined(USB_OTG_FS) || defined(USB_OTG_HS)
132 if (packet_size_limit > fifo_size_)
133 {
134 packet_size_limit = fifo_size_;
135 }
136#endif
137
138#if defined(USB_BASE)
139 if (packet_size_limit > hw_buffer_size_)
140 {
141 packet_size_limit = hw_buffer_size_;
142 }
143#endif
144
145 auto buffer = GetBuffer();
146
147 if (packet_size_limit > buffer.size_)
148 {
149 packet_size_limit = buffer.size_;
150 }
151
152 size_t max_packet_size = cfg.max_packet_size;
153
154 if (max_packet_size > packet_size_limit)
155 {
156 max_packet_size = packet_size_limit;
157 }
158
159 ep_cfg.max_packet_size = max_packet_size;
160
161 if (max_packet_size < 8)
162 {
163 max_packet_size = 8;
164 }
165
166 if (HAL_PCD_EP_Open(hpcd_, addr, max_packet_size, type) == HAL_OK)
167 {
169 }
170 else
171 {
173 }
174}
@ IN
输入方向 / IN direction
@ OUT
输出方向 / OUT direction
Config & GetConfig()
获取当前配置引用 / Get endpoint config reference
Definition ep.hpp:516
@ ISOCHRONOUS
等时端点 / Isochronous
@ BULK
批量端点 / Bulk
@ INTERRUPT
中断端点 / Interrupt
@ CONTROL
控制端点 / Control
RawData GetBuffer() const
获取当前可用于传输的缓冲区 / Get current transfer buffer
Definition ep.hpp:246

◆ MaxTransferSize()

size_t STM32Endpoint::MaxTransferSize ( ) const
overridevirtual

返回当前最大可传输字节数 / Return maximum transferable size at this time

Returns
size_t 最大可传输字节数 / Maximum transferable bytes

Reimplemented from LibXR::USB::Endpoint.

Definition at line 308 of file stm32_usb_ep.cpp.

309{
311 {
312 return MaxPacketSize();
313 }
314 else
315 {
316 return GetBuffer().size_;
317 }
318}
size_t size_
数据字节数 / Data size in bytes
uint16_t MaxPacketSize() const
获取最大包长 / Get max packet size
Definition ep.hpp:226

◆ Stall()

ErrorCode STM32Endpoint::Stall ( )
overridevirtual

置 STALL / Stall endpoint

Returns
ErrorCode 错误码 / Error code

Implements LibXR::USB::Endpoint.

Definition at line 260 of file stm32_usb_ep.cpp.

261{
262 const bool is_in = (GetDirection() == Direction::IN);
263 if (GetState() != State::IDLE && !(GetState() == State::BUSY && !is_in))
264 {
265 return ErrorCode::BUSY;
266 }
267
268 uint8_t addr = EPNumberToAddr(GetNumber(), GetDirection());
269 if (HAL_PCD_EP_SetStall(hpcd_, addr) == HAL_OK)
270 {
272 return ErrorCode::OK;
273 }
274 else
275 {
277 return ErrorCode::FAILED;
278 }
279}
@ BUSY
忙碌 | Busy

◆ Transfer()

ErrorCode STM32Endpoint::Transfer ( size_t size)
overridevirtual

启动一次传输 / Start a transfer

Parameters
size传输长度 / Transfer size
Returns
ErrorCode 错误码 / Error code

Implements LibXR::USB::Endpoint.

Definition at line 183 of file stm32_usb_ep.cpp.

184{
185 if (GetState() == State::BUSY)
186 {
187 return ErrorCode::BUSY;
188 }
189
190 bool is_in = GetDirection() == Direction::IN;
191 auto ep_addr = EPNumberToAddr(GetNumber(), GetDirection());
192
193 PCD_EPTypeDef* ep = is_in ? &hpcd_->IN_ep[ep_addr & EP_ADDR_MSK]
194 : &hpcd_->OUT_ep[ep_addr & EP_ADDR_MSK];
195
196 auto buffer = GetBuffer();
197
198 if (buffer.size_ < size)
199 {
200 return ErrorCode::NO_BUFF;
201 }
202
203 ep->xfer_buff = reinterpret_cast<uint8_t*>(buffer.addr_);
204
205 if (UseDoubleBuffer() && GetDirection() == Direction::IN && size > 0)
206 {
207 SwitchBuffer();
208 }
209
210 ep->xfer_len = size;
211 ep->xfer_count = 0U;
212 ep->is_in = is_in ? 1U : 0U;
213 ep->num = ep_addr & EP_ADDR_MSK;
214 last_transfer_size_ = size;
215
216#if defined(USB_OTG_FS) || defined(USB_OTG_HS)
217 if (hpcd_->Init.dma_enable == 1U)
218 {
219 ep->dma_addr = reinterpret_cast<uint32_t>(ep->xfer_buff);
220
221 if (is_in == true)
222 {
223 STM32_CleanDCacheByAddr(buffer.addr_, size);
224 }
225 }
226#endif
227
228#if defined(USB_BASE)
229 if (is_in)
230 {
231 ep->xfer_fill_db = 0U;
232 ep->xfer_len_db = 0U;
233 }
234#endif
235
237
238#if defined(USB_OTG_FS) || defined(USB_OTG_HS)
239 auto ans = USB_EPStartXfer(hpcd_->Instance, ep, hpcd_->Init.dma_enable);
240#else
241 auto ans = USB_EPStartXfer(hpcd_->Instance, ep);
242 if (size == 0 && GetNumber() == USB::Endpoint::EPNumber::EP0 &&
244 {
246 }
247#endif
248
249 if (ans == HAL_OK)
250 {
251 return ErrorCode::OK;
252 }
253 else
254 {
256 return ErrorCode::FAILED;
257 }
258}
bool UseDoubleBuffer() const
是否启用双缓冲 / Whether double buffer is enabled
Definition ep.hpp:240
virtual void SwitchBuffer()
切换双缓冲 / Switch double buffer
Definition ep.hpp:521
void OnTransferCompleteCallback(bool in_isr, size_t actual_transfer_size)
由底层在传输完成时调用 / Called by low-level driver when transfer completes
Definition ep.hpp:393
@ NO_BUFF
缓冲区不足 | Insufficient buffer
void STM32_CleanDCacheByAddr(const void *addr, size_t size)
Cleans D-Cache lines covering the specified memory range.

Field Documentation

◆ hpcd_

PCD_HandleTypeDef* LibXR::STM32Endpoint::hpcd_

Definition at line 39 of file stm32_usb_ep.hpp.

◆ id_

stm32_usb_dev_id_t LibXR::STM32Endpoint::id_

Definition at line 49 of file stm32_usb_ep.hpp.

◆ last_transfer_size_

size_t LibXR::STM32Endpoint::last_transfer_size_ = 0

Definition at line 41 of file stm32_usb_ep.hpp.


The documentation for this class was generated from the following files: