3#include "ch32_usb_endpoint.hpp"
31 *GetDmaAddr(ep_num) = (uint32_t)value;
34 case USB::Endpoint::EPNumber::EP1:
35 USBFSD->UEP4_1_MOD |= USBFS_UEP1_BUF_MOD;
37 case USB::Endpoint::EPNumber::EP2:
38 USBFSD->UEP2_3_MOD |= USBFS_UEP2_BUF_MOD;
40 case USB::Endpoint::EPNumber::EP3:
41 USBFSD->UEP2_3_MOD |= USBFS_UEP3_BUF_MOD;
43 case USB::Endpoint::EPNumber::EP4:
44 USBFSD->UEP4_1_MOD |= USBFS_UEP4_BUF_MOD;
46 case USB::Endpoint::EPNumber::EP5:
47 USBFSD->UEP5_6_MOD |= USBFS_UEP5_BUF_MOD;
49 case USB::Endpoint::EPNumber::EP6:
50 USBFSD->UEP5_6_MOD |= USBFS_UEP6_BUF_MOD;
52 case USB::Endpoint::EPNumber::EP7:
53 USBFSD->UEP7_MOD |= USBFS_UEP7_BUF_MOD;
62 *GetTxLenAddr(ep_num) = value;
69 case USB::Endpoint::EPNumber::EP1:
70 USBFSD->UEP4_1_MOD |= USBFS_UEP1_TX_EN;
72 case USB::Endpoint::EPNumber::EP2:
73 USBFSD->UEP2_3_MOD |= USBFS_UEP2_TX_EN;
75 case USB::Endpoint::EPNumber::EP3:
76 USBFSD->UEP2_3_MOD |= USBFS_UEP3_TX_EN;
78 case USB::Endpoint::EPNumber::EP4:
79 USBFSD->UEP4_1_MOD |= USBFS_UEP4_TX_EN;
81 case USB::Endpoint::EPNumber::EP5:
82 USBFSD->UEP5_6_MOD |= USBFS_UEP5_TX_EN;
84 case USB::Endpoint::EPNumber::EP6:
85 USBFSD->UEP5_6_MOD |= USBFS_UEP6_TX_EN;
87 case USB::Endpoint::EPNumber::EP7:
88 USBFSD->UEP7_MOD |= USBFS_UEP7_TX_EN;
98 case USB::Endpoint::EPNumber::EP1:
99 USBFSD->UEP4_1_MOD &= ~USBFS_UEP1_TX_EN;
101 case USB::Endpoint::EPNumber::EP2:
102 USBFSD->UEP2_3_MOD &= ~USBFS_UEP2_TX_EN;
104 case USB::Endpoint::EPNumber::EP3:
105 USBFSD->UEP2_3_MOD &= ~USBFS_UEP3_TX_EN;
107 case USB::Endpoint::EPNumber::EP4:
108 USBFSD->UEP4_1_MOD &= ~USBFS_UEP4_TX_EN;
110 case USB::Endpoint::EPNumber::EP5:
111 USBFSD->UEP5_6_MOD &= ~USBFS_UEP5_TX_EN;
113 case USB::Endpoint::EPNumber::EP6:
114 USBFSD->UEP5_6_MOD &= ~USBFS_UEP6_TX_EN;
116 case USB::Endpoint::EPNumber::EP7:
117 USBFSD->UEP7_MOD &= ~USBFS_UEP7_TX_EN;
127 case USB::Endpoint::EPNumber::EP1:
128 USBFSD->UEP4_1_MOD |= USBFS_UEP1_RX_EN;
130 case USB::Endpoint::EPNumber::EP2:
131 USBFSD->UEP2_3_MOD |= USBFS_UEP2_RX_EN;
133 case USB::Endpoint::EPNumber::EP3:
134 USBFSD->UEP2_3_MOD |= USBFS_UEP3_RX_EN;
136 case USB::Endpoint::EPNumber::EP4:
137 USBFSD->UEP4_1_MOD |= USBFS_UEP4_RX_EN;
139 case USB::Endpoint::EPNumber::EP5:
140 USBFSD->UEP5_6_MOD |= USBFS_UEP5_RX_EN;
142 case USB::Endpoint::EPNumber::EP6:
143 USBFSD->UEP5_6_MOD |= USBFS_UEP6_RX_EN;
145 case USB::Endpoint::EPNumber::EP7:
146 USBFSD->UEP7_MOD |= USBFS_UEP7_RX_EN;
156 case USB::Endpoint::EPNumber::EP1:
157 USBFSD->UEP4_1_MOD &= ~USBFS_UEP1_RX_EN;
159 case USB::Endpoint::EPNumber::EP2:
160 USBFSD->UEP2_3_MOD &= ~USBFS_UEP2_RX_EN;
162 case USB::Endpoint::EPNumber::EP3:
163 USBFSD->UEP2_3_MOD &= ~USBFS_UEP3_RX_EN;
165 case USB::Endpoint::EPNumber::EP4:
166 USBFSD->UEP4_1_MOD &= ~USBFS_UEP4_RX_EN;
168 case USB::Endpoint::EPNumber::EP5:
169 USBFSD->UEP5_6_MOD &= ~USBFS_UEP5_RX_EN;
171 case USB::Endpoint::EPNumber::EP6:
172 USBFSD->UEP5_6_MOD &= ~USBFS_UEP6_RX_EN;
174 case USB::Endpoint::EPNumber::EP7:
175 USBFSD->UEP7_MOD &= ~USBFS_UEP7_RX_EN;
188 if (ep_num == USB::Endpoint::EPNumber::EP0)
194 if (dir == USB::Endpoint::Direction::OUT)
205CH32EndpointOtgFs::CH32EndpointOtgFs(EPNumber ep_num, Direction dir,
207 : Endpoint(ep_num, dir, SelectBuffer(ep_num, dir, buffer)), dma_buffer_(buffer)
209 map_otg_fs_[EPNumberToInt8(GetNumber())][
static_cast<uint8_t
>(dir)] =
this;
211 SetDmaBuffer(GetNumber(), dma_buffer_.addr_);
213 if (dir == Direction::IN)
215 SetTxLen(GetNumber(), 0);
216 *GetTxCtrlAddr(GetNumber()) = USBFS_UEP_T_RES_NAK;
220 *GetRxCtrlAddr(GetNumber()) = USBFS_UEP_R_RES_NAK;
228 ep_cfg.max_packet_size = 64;
232 ep_cfg.double_buffer =
true;
236 ep_cfg.double_buffer =
false;
239 *GetRxCtrlAddr(
GetNumber()) = USBFS_UEP_R_RES_NAK | USBFS_UEP_R_AUTO_TOG;
240 *GetTxCtrlAddr(
GetNumber()) = USBFS_UEP_T_RES_NAK | USBFS_UEP_T_AUTO_TOG;
256 *GetTxCtrlAddr(
GetNumber()) = USBFS_UEP_T_RES_NAK;
257 *GetRxCtrlAddr(
GetNumber()) = USBFS_UEP_R_RES_NAK;
266 return ErrorCode::BUSY;
270 if (buffer.
size_ < size)
272 return ErrorCode::NO_BUFF;
289 *addr = USBFS_UEP_T_RES_ACK | (*addr & (~USBFS_UEP_T_RES_MASK));
293 *addr = USBFS_UEP_T_RES_ACK | (tog_ ? USBFS_UEP_T_TOG : 0);
302 *addr = USBFS_UEP_R_RES_ACK | (*addr & (~USBFS_UEP_R_RES_MASK));
306 *addr = USBFS_UEP_R_RES_ACK | (tog_ ? USBFS_UEP_R_TOG : 0);
315 last_transfer_size_ = size;
317 return ErrorCode::OK;
324 return ErrorCode::BUSY;
330 *GetTxCtrlAddr(
GetNumber()) |= USBFS_UEP_T_RES_STALL;
334 *GetRxCtrlAddr(
GetNumber()) |= USBFS_UEP_R_RES_STALL;
337 return ErrorCode::OK;
344 return ErrorCode::FAILED;
350 *GetTxCtrlAddr(
GetNumber()) &= ~USBFS_UEP_T_RES_STALL;
354 *GetRxCtrlAddr(
GetNumber()) &= ~USBFS_UEP_R_RES_STALL;
357 return ErrorCode::OK;
360void CH32EndpointOtgFs::TransferComplete(
size_t size)
364 size = last_transfer_size_;
368 (USBFSD->INT_FG & USBFS_U_TOG_OK) != USBFS_U_TOG_OK)
376 *GetRxCtrlAddr(
GetNumber()) = USBFS_UEP_R_RES_ACK;
382 (*GetTxCtrlAddr(
GetNumber()) & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
383 USBFSD->INT_FG = USBFS_UIF_TRANSFER;
386 OnTransferCompleteCallback(
false, size);
393 tog_ = (*GetTxCtrlAddr(
GetNumber()) & USBFS_UEP_T_TOG) == USBFS_UEP_T_TOG;
398 tog_ = (*GetRxCtrlAddr(
GetNumber()) & USBFS_UEP_R_TOG) == USBFS_UEP_R_TOG;
void SwitchBuffer() override
切换缓冲区 Switch buffer
ErrorCode ClearStall() override
清除端点停止状态 Clear endpoint stop status
void Close() override
关闭端点(软禁用/资源复位) Close (soft disable)
ErrorCode Stall() override
停止端点传输 Stop endpoint transfer
void Configure(const Config &cfg) override
二次初始化/配置端点协议参数(由Pool/Manager分配后调用) Configure endpoint protocol parameters (call after pool allocation...
ErrorCode Transfer(size_t size) override
传输数据 Transfer data
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
void * addr_
数据存储地址。 The storage address of the data.
EPNumber
端点号 / Endpoint number
static constexpr uint8_t EPNumberToInt8(EPNumber ep)
端点号转换为uint8_t / Convert endpoint number to uint8_t
Direction
端点方向 Endpoint direction
@ OUT
输出方向 / OUT direction
Direction GetDirection() const
获取端点方向 Get endpoint direction
bool UseDoubleBuffer() const
是否使用双缓冲区 / Use double buffer
Config & GetConfig()
获取当前配置 Get endpoint config
EPNumber GetNumber() const
获取端点号 Get endpoint number
virtual void SetActiveBlock(bool active_block)
设置当前活动缓冲区 Set active buffer
void SetState(State state)
设置端点状态 Set endpoint state
State GetState() const
获取端点状态 Get endpoint state
RawData GetBuffer() const
获取端点缓冲区 Get endpoint buffer