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)
201 if (dir == USB::Endpoint::Direction::OUT)
212CH32EndpointOtgFs::CH32EndpointOtgFs(EPNumber ep_num, Direction dir,
214 : Endpoint(ep_num, dir, is_isochronous ? buffer : select_buffer(ep_num, dir, buffer)),
215 is_isochronous_(is_isochronous),
218 map_otg_fs_[EPNumberToInt8(GetNumber())][
static_cast<uint8_t
>(dir)] =
this;
220 set_dma_buffer(GetNumber(), dma_buffer_.addr_, is_isochronous ?
false :
true);
222 if (dir == Direction::IN)
224 set_tx_len(GetNumber(), 0);
225 *get_tx_ctrl_addr(GetNumber()) = USBFS_UEP_T_RES_NAK;
229 *get_rx_ctrl_addr(GetNumber()) = USBFS_UEP_R_RES_NAK;
233void CH32EndpointOtgFs::Configure(
const Config& cfg)
235 auto& ep_cfg = GetConfig();
238 if (GetNumber() != EPNumber::EP0 && !is_isochronous_)
240 ep_cfg.double_buffer =
true;
244 ep_cfg.double_buffer =
false;
247 ep_cfg.max_packet_size = GetBuffer().size_;
249 set_tx_len(GetNumber(), 0);
251 if (!is_isochronous_)
253 *get_rx_ctrl_addr(GetNumber()) = USBFS_UEP_R_RES_NAK | USBFS_UEP_R_AUTO_TOG;
254 *get_tx_ctrl_addr(GetNumber()) = USBFS_UEP_T_RES_NAK | USBFS_UEP_T_AUTO_TOG;
255 enable_tx(GetNumber());
256 enable_rx(GetNumber());
260 *get_rx_ctrl_addr(GetNumber()) = USBFS_UEP_R_RES_NAK;
261 *get_tx_ctrl_addr(GetNumber()) = USBFS_UEP_T_RES_NAK;
262 if (GetDirection() == Direction::IN)
264 enable_tx(GetNumber());
268 enable_rx(GetNumber());
272 set_dma_buffer(GetNumber(), dma_buffer_.addr_, is_isochronous_ ?
false :
true);
274 SetState(State::IDLE);
277void CH32EndpointOtgFs::Close()
279 disable_tx(GetNumber());
280 disable_rx(GetNumber());
282 *get_tx_ctrl_addr(GetNumber()) = USBFS_UEP_T_RES_NAK;
283 *get_rx_ctrl_addr(GetNumber()) = USBFS_UEP_R_RES_NAK;
285 SetState(State::DISABLED);
288ErrorCode CH32EndpointOtgFs::Transfer(
size_t size)
290 if (GetState() == State::BUSY)
292 return ErrorCode::BUSY;
295 auto buffer = GetBuffer();
296 if (buffer.
size_ < size)
298 return ErrorCode::NO_BUFF;
301 bool is_in = (GetDirection() == Direction::IN);
303 if (is_in && UseDoubleBuffer())
310 set_tx_len(GetNumber(), size);
311 auto addr = get_tx_ctrl_addr(GetNumber());
313 if (GetNumber() != EPNumber::EP0)
315 *addr = (is_isochronous_ ? USBFS_UEP_T_RES_NONE : USBFS_UEP_T_RES_ACK) |
316 (*addr & (~USBFS_UEP_T_RES_MASK));
320 *addr = USBFS_UEP_T_RES_ACK | (tog_ ? USBFS_UEP_T_TOG : 0);
325 auto addr = get_rx_ctrl_addr(GetNumber());
327 if (GetNumber() != EPNumber::EP0)
329 *addr = (is_isochronous_ ? USBFS_UEP_R_RES_NONE : USBFS_UEP_R_RES_ACK) |
330 (*addr & (~USBFS_UEP_R_RES_MASK));
334 *addr = USBFS_UEP_R_RES_ACK | (tog_ ? USBFS_UEP_R_TOG : 0);
338 if (GetNumber() == EPNumber::EP0)
343 last_transfer_size_ = size;
344 SetState(State::BUSY);
345 return ErrorCode::OK;
348ErrorCode CH32EndpointOtgFs::Stall()
350 if (GetState() != State::IDLE)
352 return ErrorCode::BUSY;
355 bool is_in = (GetDirection() == Direction::IN);
358 *get_tx_ctrl_addr(GetNumber()) |= USBFS_UEP_T_RES_STALL;
362 *get_rx_ctrl_addr(GetNumber()) |= USBFS_UEP_R_RES_STALL;
364 SetState(State::STALLED);
365 return ErrorCode::OK;
368ErrorCode CH32EndpointOtgFs::ClearStall()
370 if (GetState() != State::STALLED)
372 return ErrorCode::FAILED;
375 bool is_in = (GetDirection() == Direction::IN);
378 *get_tx_ctrl_addr(GetNumber()) &= ~USBFS_UEP_T_RES_STALL;
382 *get_rx_ctrl_addr(GetNumber()) &= ~USBFS_UEP_R_RES_STALL;
384 SetState(State::IDLE);
385 return ErrorCode::OK;
388void CH32EndpointOtgFs::TransferComplete(
size_t size)
390 const bool IS_IN = (GetDirection() == Direction::IN);
391 const bool IS_OUT = !IS_IN;
392 const bool IS_EP0 = (GetNumber() == EPNumber::EP0);
393 const bool IS_ISO = (GetType() == Type::ISOCHRONOUS);
400 *get_tx_ctrl_addr(GetNumber()) =
401 (*get_tx_ctrl_addr(GetNumber()) & ~USBFS_UEP_T_RES_MASK) | USBFS_UEP_T_RES_NAK;
403 size = last_transfer_size_;
410 *get_rx_ctrl_addr(GetNumber()) =
411 (*get_rx_ctrl_addr(GetNumber()) & ~USBFS_UEP_R_RES_MASK) | USBFS_UEP_R_RES_NAK;
418 const bool TOG_OK = ((USBFSD->INT_ST & USBFS_U_TOG_OK) == USBFS_U_TOG_OK);
421 SetState(State::IDLE);
422 (void)Transfer(last_transfer_size_);
428 if (GetState() == State::BUSY && !IS_EP0 && !IS_ISO)
433 if (IS_EP0 && IS_OUT)
436 *get_rx_ctrl_addr(GetNumber()) = USBFS_UEP_R_RES_ACK;
439 OnTransferCompleteCallback(
true, size);
442void CH32EndpointOtgFs::SwitchBuffer()
444 if (GetDirection() == Direction::IN)
446 tog_ = (*get_tx_ctrl_addr(GetNumber()) & USBFS_UEP_T_TOG) == USBFS_UEP_T_TOG;
447 SetActiveBlock(!tog_);
451 tog_ = (*get_rx_ctrl_addr(GetNumber()) & USBFS_UEP_R_TOG) == USBFS_UEP_R_TOG;
452 SetActiveBlock(tog_);
原始数据封装类。 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