1#include "stm32_usb_ep.hpp"
5#if defined(HAL_PCD_MODULE_ENABLED)
7static inline bool is_power_of_two(
unsigned int n) {
return n > 0 && (n & (n - 1)) == 0; }
9#if defined(USB_OTG_HS) || defined(USB_OTG_FS)
11STM32Endpoint::STM32Endpoint(EPNumber ep_num, stm32_usb_dev_id_t
id,
12 PCD_HandleTypeDef* hpcd, Direction dir,
size_t fifo_size,
14 : Endpoint(ep_num, dir, buffer), hpcd_(hpcd), fifo_size_(fifo_size), id_(id)
16 ASSERT(fifo_size >= 8);
17 ASSERT(is_power_of_two(fifo_size) || fifo_size % 4 == 0);
18 ASSERT(is_power_of_two(buffer.
size_) || buffer.
size_ % 4 == 0);
20#if defined(USB_OTG_HS)
21 if (
id == STM32_USB_OTG_HS)
23 map_hs_[EPNumberToInt8(GetNumber())][
static_cast<uint8_t
>(dir)] =
this;
26#if defined(USB_OTG_FS)
27 if (
id == STM32_USB_OTG_FS)
29 map_fs_[EPNumberToInt8(GetNumber())][
static_cast<uint8_t
>(dir)] =
this;
33 if (dir == Direction::IN)
35 HAL_PCDEx_SetTxFiFo(hpcd_, EPNumberToInt8(GetNumber()), fifo_size / 4);
37 else if (dir == Direction::OUT && ep_num == USB::Endpoint::EPNumber::EP0)
39 HAL_PCDEx_SetRxFiFo(hpcd_, fifo_size / 4);
45STM32Endpoint::STM32Endpoint(EPNumber ep_num, stm32_usb_dev_id_t
id,
46 PCD_HandleTypeDef* hpcd, Direction dir,
47 size_t hw_buffer_offset,
size_t hw_buffer_size,
49 : Endpoint(ep_num, dir, buffer),
51 hw_buffer_size_(hw_buffer_size),
52 double_hw_buffer_(double_hw_buffer),
55 ASSERT(hw_buffer_size >= 8);
57 ASSERT(is_power_of_two(hw_buffer_size));
58 ASSERT(is_power_of_two(buffer.
size_) || buffer.
size_ % 4 == 0);
60 map_otg_fs_[EPNumberToInt8(GetNumber())][
static_cast<uint8_t
>(dir)] =
this;
62 size_t buffer_offset = hw_buffer_offset / 2;
66 buffer_offset |= ((buffer_offset + hw_buffer_size / 2) << 16);
69 HAL_PCDEx_PMAConfig(hpcd_, EPNumberToAddr(GetNumber(), dir),
70 double_hw_buffer ? PCD_DBL_BUF : PCD_SNG_BUF, buffer_offset);
79 uint8_t type =
static_cast<uint8_t
>(cfg.
type);
81 size_t packet_size_limit = 0;
88#if defined(PCD_SPEED_HIGH_IN_FULL)
89 if (hpcd_->Init.speed == PCD_SPEED_FULL ||
90 hpcd_->Init.speed == PCD_SPEED_HIGH_IN_FULL)
92 if (hpcd_->Init.speed == PCD_SPEED_FULL)
95 packet_size_limit = 64;
99 packet_size_limit = 512;
103#if defined(PCD_SPEED_HIGH_IN_FULL)
104 if (hpcd_->Init.speed == PCD_SPEED_FULL ||
105 hpcd_->Init.speed == PCD_SPEED_HIGH_IN_FULL)
107 if (hpcd_->Init.speed == PCD_SPEED_FULL)
110 packet_size_limit = 64;
114 packet_size_limit = 1024;
118#if defined(PCD_SPEED_HIGH_IN_FULL)
119 if (hpcd_->Init.speed == PCD_SPEED_FULL ||
120 hpcd_->Init.speed == PCD_SPEED_HIGH_IN_FULL)
122 if (hpcd_->Init.speed == PCD_SPEED_FULL)
125 packet_size_limit = 1023;
129 packet_size_limit = 1024;
133 packet_size_limit = 64;
139#if defined(USB_OTG_FS) || defined(USB_OTG_HS)
140 if (packet_size_limit > fifo_size_)
142 packet_size_limit = fifo_size_;
147 if (packet_size_limit > hw_buffer_size_)
149 packet_size_limit = hw_buffer_size_;
155 if (packet_size_limit > buffer.
size_)
157 packet_size_limit = buffer.
size_;
162 if (max_packet_size > packet_size_limit)
164 max_packet_size = packet_size_limit;
167 ep_cfg.max_packet_size = max_packet_size;
169 if (max_packet_size < 8)
174 if (HAL_PCD_EP_Open(hpcd_, addr, max_packet_size, type) == HAL_OK)
187 HAL_PCD_EP_Close(hpcd_, addr);
195 return ErrorCode::BUSY;
201 PCD_EPTypeDef* ep = is_in ? &hpcd_->IN_ep[ep_addr & EP_ADDR_MSK]
202 : &hpcd_->OUT_ep[ep_addr & EP_ADDR_MSK];
206 if (buffer.
size_ < size)
208 return ErrorCode::NO_BUFF;
211 ep->xfer_buff =
reinterpret_cast<uint8_t*
>(buffer.
addr_);
220 ep->is_in = is_in ? 1U : 0U;
221 ep->num = ep_addr & EP_ADDR_MSK;
223#if defined(USB_OTG_FS) || defined(USB_OTG_HS)
224 if (hpcd_->Init.dma_enable == 1U)
226 ep->dma_addr =
reinterpret_cast<uint32_t
>(ep->xfer_buff);
228#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
231 SCB_CleanDCache_by_Addr(
reinterpret_cast<uint32_t*
>(buffer.
addr_),
232 static_cast<int32_t
>(size));
241 ep->xfer_fill_db = 1U;
242 ep->xfer_len_db = size;
248#if defined(USB_OTG_FS) || defined(USB_OTG_HS)
249 auto ans = USB_EPStartXfer(hpcd_->Instance, ep, hpcd_->Init.dma_enable);
251 auto ans = USB_EPStartXfer(hpcd_->Instance, ep);
261 return ErrorCode::OK;
266 return ErrorCode::FAILED;
274 return ErrorCode::BUSY;
278 if (HAL_PCD_EP_SetStall(hpcd_, addr) == HAL_OK)
281 return ErrorCode::OK;
286 return ErrorCode::FAILED;
294 return ErrorCode::FAILED;
302 return ErrorCode::OK;
305 if (HAL_PCD_EP_ClrStall(hpcd_, addr) == HAL_OK)
308 return ErrorCode::OK;
313 return ErrorCode::FAILED;
331static STM32Endpoint* GetEndpoint(PCD_HandleTypeDef* hpcd, uint8_t epnum,
bool is_in)
333 auto id = STM32USBDeviceGetID(hpcd);
334#if defined(USB_OTG_HS)
335 if (
id == STM32_USB_OTG_HS)
337 return STM32Endpoint::map_hs_[epnum & 0x7F][
static_cast<uint8_t
>(is_in)];
340#if defined(USB_OTG_FS)
341 if (
id == STM32_USB_OTG_FS)
343 return STM32Endpoint::map_fs_[epnum & 0x7F][
static_cast<uint8_t
>(is_in)];
347 if (
id == STM32_USB_FS_DEV)
349 return STM32Endpoint::map_otg_fs_[epnum & 0x7F][
static_cast<uint8_t
>(is_in)];
355extern "C" void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum)
357 auto id = STM32USBDeviceGetID(hpcd);
359 ASSERT(
id < STM32_USB_DEV_ID_NUM);
361 auto ep = GetEndpoint(hpcd, epnum,
true);
363 if (!ep || ep->hpcd_ != hpcd)
368 PCD_EPTypeDef* ep_handle = &hpcd->IN_ep[epnum & EP_ADDR_MSK];
370 size_t actual_transfer_size = ep_handle->xfer_count;
372 ep->OnTransferCompleteCallback(
true, actual_transfer_size);
375extern "C" void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum)
377 auto id = STM32USBDeviceGetID(hpcd);
379 ASSERT(
id < STM32_USB_DEV_ID_NUM);
381 auto ep = GetEndpoint(hpcd, epnum,
false);
383 if (!ep || ep->hpcd_ != hpcd)
388 PCD_EPTypeDef* ep_handle = &hpcd->OUT_ep[epnum & EP_ADDR_MSK];
390 size_t actual_transfer_size = ep_handle->xfer_count;
392#if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U)
393 SCB_InvalidateDCache_by_Addr(ep->GetBuffer().addr_,
394 static_cast<int32_t
>(actual_transfer_size));
397 ep->OnTransferCompleteCallback(
true, actual_transfer_size);
400extern "C" void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum)
402 auto id = STM32USBDeviceGetID(hpcd);
404 ASSERT(
id < STM32_USB_DEV_ID_NUM);
406 auto ep = GetEndpoint(hpcd, epnum,
true);
408 if (!ep || ep->hpcd_ != hpcd)
413 ep->OnTransferCompleteCallback(
true, 0);
416extern "C" void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef* hpcd, uint8_t epnum)
418 auto id = STM32USBDeviceGetID(hpcd);
420 ASSERT(
id < STM32_USB_DEV_ID_NUM);
422 auto ep = GetEndpoint(hpcd, epnum,
false);
424 if (!ep || ep->hpcd_ != hpcd)
429 ep->OnTransferCompleteCallback(
true, 0);
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
ErrorCode Transfer(size_t size) override
启动一次传输 / Start a transfer
ErrorCode ClearStall() override
清除 STALL / Clear stall
void Configure(const Config &cfg) override
配置端点协议参数 / Configure endpoint protocol parameters
void Close() override
关闭端点 / Close endpoint
ErrorCode Stall() override
置 STALL / Stall endpoint
size_t MaxTransferSize() const override
返回当前最大可传输字节数 / Return maximum transferable size at this time
@ OUT
输出方向 / OUT direction
static constexpr uint8_t EPNumberToAddr(EPNumber ep, Direction dir)
端点号转换为端点地址 / Convert endpoint number to endpoint address
Direction GetDirection() const
获取当前端点方向 / Get current endpoint direction
bool UseDoubleBuffer() const
是否启用双缓冲 / Whether double buffer is enabled
virtual void SwitchBuffer()
切换双缓冲 / Switch double buffer
Config & GetConfig()
获取当前配置引用 / Get endpoint config reference
void OnTransferCompleteCallback(bool in_isr, size_t actual_transfer_size)
由底层在传输完成时调用 / Called by low-level driver when transfer completes
@ ISOCHRONOUS
等时端点 / Isochronous
@ INTERRUPT
中断端点 / Interrupt
EPNumber GetNumber() const
获取端点号 / Get endpoint number
uint16_t MaxPacketSize() const
获取最大包长 / Get max packet size
void SetState(State state)
设置端点状态 / Set endpoint state
State GetState() const
获取端点状态 / Get endpoint state
RawData GetBuffer() const
获取当前可用于传输的缓冲区 / Get current transfer buffer
端点配置参数 / Endpoint configuration parameters
Type type
端点类型 / Endpoint type
uint16_t max_packet_size
最大包长 / Max packet size
Direction direction
端点方向 / Endpoint direction