3#include "ch32_usb_endpoint.hpp"
32 *get_dma_addr(ep_num) = (uint32_t)value;
41 case USB::Endpoint::EPNumber::EP1:
42 USBFSD->UEP4_1_MOD |= USBFS_UEP1_BUF_MOD;
44 case USB::Endpoint::EPNumber::EP2:
45 USBFSD->UEP2_3_MOD |= USBFS_UEP2_BUF_MOD;
47 case USB::Endpoint::EPNumber::EP3:
48 USBFSD->UEP2_3_MOD |= USBFS_UEP3_BUF_MOD;
50 case USB::Endpoint::EPNumber::EP4:
51 USBFSD->UEP4_1_MOD |= USBFS_UEP4_BUF_MOD;
53 case USB::Endpoint::EPNumber::EP5:
54 USBFSD->UEP5_6_MOD |= USBFS_UEP5_BUF_MOD;
56 case USB::Endpoint::EPNumber::EP6:
57 USBFSD->UEP5_6_MOD |= USBFS_UEP6_BUF_MOD;
59 case USB::Endpoint::EPNumber::EP7:
60 USBFSD->UEP7_MOD |= USBFS_UEP7_BUF_MOD;
69 *get_tx_len_addr(ep_num) = value;
76 case USB::Endpoint::EPNumber::EP1:
77 USBFSD->UEP4_1_MOD |= USBFS_UEP1_TX_EN;
79 case USB::Endpoint::EPNumber::EP2:
80 USBFSD->UEP2_3_MOD |= USBFS_UEP2_TX_EN;
82 case USB::Endpoint::EPNumber::EP3:
83 USBFSD->UEP2_3_MOD |= USBFS_UEP3_TX_EN;
85 case USB::Endpoint::EPNumber::EP4:
86 USBFSD->UEP4_1_MOD |= USBFS_UEP4_TX_EN;
88 case USB::Endpoint::EPNumber::EP5:
89 USBFSD->UEP5_6_MOD |= USBFS_UEP5_TX_EN;
91 case USB::Endpoint::EPNumber::EP6:
92 USBFSD->UEP5_6_MOD |= USBFS_UEP6_TX_EN;
94 case USB::Endpoint::EPNumber::EP7:
95 USBFSD->UEP7_MOD |= USBFS_UEP7_TX_EN;
105 case USB::Endpoint::EPNumber::EP1:
106 USBFSD->UEP4_1_MOD &= ~USBFS_UEP1_TX_EN;
108 case USB::Endpoint::EPNumber::EP2:
109 USBFSD->UEP2_3_MOD &= ~USBFS_UEP2_TX_EN;
111 case USB::Endpoint::EPNumber::EP3:
112 USBFSD->UEP2_3_MOD &= ~USBFS_UEP3_TX_EN;
114 case USB::Endpoint::EPNumber::EP4:
115 USBFSD->UEP4_1_MOD &= ~USBFS_UEP4_TX_EN;
117 case USB::Endpoint::EPNumber::EP5:
118 USBFSD->UEP5_6_MOD &= ~USBFS_UEP5_TX_EN;
120 case USB::Endpoint::EPNumber::EP6:
121 USBFSD->UEP5_6_MOD &= ~USBFS_UEP6_TX_EN;
123 case USB::Endpoint::EPNumber::EP7:
124 USBFSD->UEP7_MOD &= ~USBFS_UEP7_TX_EN;
134 case USB::Endpoint::EPNumber::EP1:
135 USBFSD->UEP4_1_MOD |= USBFS_UEP1_RX_EN;
137 case USB::Endpoint::EPNumber::EP2:
138 USBFSD->UEP2_3_MOD |= USBFS_UEP2_RX_EN;
140 case USB::Endpoint::EPNumber::EP3:
141 USBFSD->UEP2_3_MOD |= USBFS_UEP3_RX_EN;
143 case USB::Endpoint::EPNumber::EP4:
144 USBFSD->UEP4_1_MOD |= USBFS_UEP4_RX_EN;
146 case USB::Endpoint::EPNumber::EP5:
147 USBFSD->UEP5_6_MOD |= USBFS_UEP5_RX_EN;
149 case USB::Endpoint::EPNumber::EP6:
150 USBFSD->UEP5_6_MOD |= USBFS_UEP6_RX_EN;
152 case USB::Endpoint::EPNumber::EP7:
153 USBFSD->UEP7_MOD |= USBFS_UEP7_RX_EN;
163 case USB::Endpoint::EPNumber::EP1:
164 USBFSD->UEP4_1_MOD &= ~USBFS_UEP1_RX_EN;
166 case USB::Endpoint::EPNumber::EP2:
167 USBFSD->UEP2_3_MOD &= ~USBFS_UEP2_RX_EN;
169 case USB::Endpoint::EPNumber::EP3:
170 USBFSD->UEP2_3_MOD &= ~USBFS_UEP3_RX_EN;
172 case USB::Endpoint::EPNumber::EP4:
173 USBFSD->UEP4_1_MOD &= ~USBFS_UEP4_RX_EN;
175 case USB::Endpoint::EPNumber::EP5:
176 USBFSD->UEP5_6_MOD &= ~USBFS_UEP5_RX_EN;
178 case USB::Endpoint::EPNumber::EP6:
179 USBFSD->UEP5_6_MOD &= ~USBFS_UEP6_RX_EN;
181 case USB::Endpoint::EPNumber::EP7:
182 USBFSD->UEP7_MOD &= ~USBFS_UEP7_RX_EN;
195 if (ep_num == USB::Endpoint::EPNumber::EP0)
200 const size_t half = buffer.
size_ / 2u;
203 if (dir == USB::Endpoint::Direction::OUT)
211CH32EndpointOtgFs::CH32EndpointOtgFs(EPNumber ep_num, Direction dir,
213 : Endpoint(ep_num, dir,
214 (single_direction || ep_num == EPNumber::EP0)
216 : select_buffer(ep_num, dir, buffer)),
217 single_direction_(single_direction),
220 map_otg_fs_[EPNumberToInt8(GetNumber())][
static_cast<uint8_t
>(dir)] =
this;
222 set_dma_buffer(GetNumber(), dma_buffer_.addr_,
false);
224 if (dir == Direction::IN)
226 set_tx_len(GetNumber(), 0);
227 *get_tx_ctrl_addr(GetNumber()) = USBFS_UEP_T_RES_NAK;
231 *get_rx_ctrl_addr(GetNumber()) = USBFS_UEP_R_RES_NAK;
242 const bool is_bidir_noniso = !is_ep0 && !single_direction_ && !is_isochronous_;
243 const bool is_single_noniso = !is_ep0 && single_direction_ && !is_isochronous_;
244 const uint16_t type_limit = is_isochronous_ ? 1023u : 64u;
252 ASSERT(dma_buffer_.
size_ >=
static_cast<size_t>(requested_mps) * 2u);
255 ep_cfg.double_buffer = is_single_noniso;
265 if (!is_isochronous_)
267 *get_rx_ctrl_addr(
GetNumber()) = USBFS_UEP_R_RES_NAK | USBFS_UEP_R_AUTO_TOG;
268 *get_tx_ctrl_addr(
GetNumber()) = USBFS_UEP_T_RES_NAK | USBFS_UEP_T_AUTO_TOG;
274 *get_rx_ctrl_addr(
GetNumber()) = USBFS_UEP_R_RES_NAK;
275 *get_tx_ctrl_addr(
GetNumber()) = USBFS_UEP_T_RES_NAK;
286 set_dma_buffer(
GetNumber(), dma_buffer_.
addr_, ep_cfg.double_buffer);
296 *get_tx_ctrl_addr(
GetNumber()) = USBFS_UEP_T_RES_NAK;
297 *get_rx_ctrl_addr(
GetNumber()) = USBFS_UEP_R_RES_NAK;
310 if (buffer.
size_ < size)
325 auto addr = get_tx_ctrl_addr(
GetNumber());
329 *addr = (is_isochronous_ ? USBFS_UEP_T_RES_NONE : USBFS_UEP_T_RES_ACK) |
330 (*addr & (~USBFS_UEP_T_RES_MASK));
334 *addr = USBFS_UEP_T_RES_ACK | (tog_ ? USBFS_UEP_T_TOG : 0);
339 auto addr = get_rx_ctrl_addr(
GetNumber());
343 *addr = (is_isochronous_ ? USBFS_UEP_R_RES_NONE : USBFS_UEP_R_RES_ACK) |
344 (*addr & (~USBFS_UEP_R_RES_MASK));
348 *addr = USBFS_UEP_R_RES_ACK | (tog_ ? USBFS_UEP_R_TOG : 0);
357 last_transfer_size_ = size;
372 *get_tx_ctrl_addr(
GetNumber()) |= USBFS_UEP_T_RES_STALL;
376 *get_rx_ctrl_addr(
GetNumber()) |= USBFS_UEP_R_RES_STALL;
392 *get_tx_ctrl_addr(
GetNumber()) &= ~USBFS_UEP_T_RES_STALL;
396 *get_rx_ctrl_addr(
GetNumber()) &= ~USBFS_UEP_R_RES_STALL;
402void CH32EndpointOtgFs::TransferComplete(
size_t size)
405 const bool IS_OUT = !IS_IN;
417 (*get_tx_ctrl_addr(
GetNumber()) & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
419 size = last_transfer_size_;
428 (*get_rx_ctrl_addr(
GetNumber()) & ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_NAK;
436 const bool TOG_OK = ((USBFSD->INT_ST & USBFS_U_TOG_OK) == USBFS_U_TOG_OK);
440 (void)
Transfer(last_transfer_size_);
452 if (IS_EP0 && IS_OUT)
455 *get_rx_ctrl_addr(
GetNumber()) = USBFS_UEP_R_RES_ACK;
465 tog_ = (*get_tx_ctrl_addr(
GetNumber()) & USBFS_UEP_T_TOG) == USBFS_UEP_T_TOG;
470 tog_ = (*get_rx_ctrl_addr(
GetNumber()) & USBFS_UEP_R_TOG) == USBFS_UEP_R_TOG;
void SwitchBuffer() override
切换双缓冲 / Switch double buffer
ErrorCode ClearStall() override
清除 STALL / Clear stall
void Close() override
关闭端点 / Close endpoint
ErrorCode Stall() override
置 STALL / Stall endpoint
void Configure(const Config &cfg) override
配置端点协议参数 / Configure endpoint protocol parameters
ErrorCode Transfer(size_t size) override
启动一次传输 / Start a transfer
可写原始数据视图 / Mutable raw data view
size_t size_
数据字节数 / Data size in bytes
void * addr_
数据起始地址 / Data start address
EPNumber
端点号 Endpoint number
Type GetType() const
获取端点类型 / Get endpoint type
static constexpr uint8_t EPNumberToInt8(EPNumber ep)
端点号转换为 uint8_t / Convert endpoint number to uint8_t
Direction
端点方向 Endpoint direction
Direction GetDirection() const
获取当前端点方向 / Get current endpoint direction
bool UseDoubleBuffer() const
是否启用双缓冲 / Whether double buffer is enabled
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
EPNumber GetNumber() const
获取端点号 / Get endpoint number
virtual void SetActiveBlock(bool active_block)
设置当前活动缓冲块 / Set active buffer block
void SetState(State state)
设置端点状态 / Set endpoint state
State GetState() const
获取端点状态 / Get endpoint state
RawData GetBuffer() const
获取当前可用于传输的缓冲区 / Get current transfer buffer
LibXR 命名空间 / LibXR namespace.
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ NO_BUFF
缓冲区不足 / Insufficient buffer
@ FAILED
操作失败 / Operation failed
@ OK
操作成功 / Operation successful
constexpr auto min(LeftType a, RightType b) -> std::common_type_t< LeftType, RightType >
计算两个数的最小值 / Computes the minimum of two numbers