3#include "ch32_usb_endpoint.hpp"
5#include "libxr_time.hpp"
15 return reinterpret_cast<volatile uint8_t*
>(
16 reinterpret_cast<volatile uint8_t*
>(&USBHSD->UEP0_TX_CTRL) +
17 static_cast<int>(ep_num) * 4);
22 return reinterpret_cast<volatile uint8_t*
>(
23 reinterpret_cast<volatile uint8_t*
>(&USBHSD->UEP0_TX_CTRL) +
24 static_cast<int>(ep_num) * 4 + 1);
29 return reinterpret_cast<volatile uint16_t*
>(
30 reinterpret_cast<volatile uint8_t*
>(&USBHSD->UEP0_TX_LEN) +
31 static_cast<int>(ep_num) * 4);
34static_assert(offsetof(USBHSD_TypeDef, UEP1_MAX_LEN) -
35 offsetof(USBHSD_TypeDef, UEP0_MAX_LEN) ==
40 return reinterpret_cast<volatile uint16_t*
>(
41 reinterpret_cast<volatile uint8_t*
>(&USBHSD->UEP0_MAX_LEN) +
42 static_cast<int>(ep_num) * 4);
47 if (ep_num == USB::Endpoint::EPNumber::EP0)
49 return &USBHSD->UEP0_DMA;
51 return reinterpret_cast<volatile uint32_t*
>(
52 reinterpret_cast<volatile uint32_t*
>(&USBHSD->UEP1_TX_DMA) +
53 (
static_cast<int>(ep_num) - 1));
58 if (ep_num == USB::Endpoint::EPNumber::EP0)
60 return &USBHSD->UEP0_DMA;
62 return reinterpret_cast<volatile uint32_t*
>(
63 reinterpret_cast<volatile uint32_t*
>(&USBHSD->UEP1_RX_DMA) +
64 (
static_cast<int>(ep_num) - 1));
69 *get_tx_len_addr(ep_num) = value;
73 uint32_t buffer_size,
bool double_buffer)
75 uint8_t* buf_base =
reinterpret_cast<uint8_t*
>(buffer);
76 uint8_t* buf_alt = buf_base + buffer_size / 2;
78 if (ep_num == USB::Endpoint::EPNumber::EP0)
80 USBHSD->UEP0_DMA = (uint32_t)buf_base;
84 *get_tx_dma_addr(ep_num) = (uint32_t)buf_base;
87 *get_rx_dma_addr(ep_num) = (uint32_t)buf_alt;
91 int IDX =
static_cast<int>(ep_num);
92 if (double_buffer && ep_num != USB::Endpoint::EPNumber::EP0)
94 USBHSD->BUF_MODE |= (1 << IDX);
98 USBHSD->BUF_MODE &= ~(1 << IDX);
103 uint32_t buffer_size,
bool double_buffer)
105 uint8_t* buf_base =
reinterpret_cast<uint8_t*
>(buffer);
106 uint8_t* buf_alt = buf_base + buffer_size / 2;
108 if (ep_num == USB::Endpoint::EPNumber::EP0)
110 USBHSD->UEP0_DMA = (uint32_t)buf_base;
114 *get_rx_dma_addr(ep_num) = (uint32_t)buf_base;
117 *get_tx_dma_addr(ep_num) = (uint32_t)buf_alt;
121 int IDX =
static_cast<int>(ep_num);
122 if (double_buffer && ep_num != USB::Endpoint::EPNumber::EP0)
124 USBHSD->BUF_MODE |= (1 << IDX);
128 USBHSD->BUF_MODE &= ~(1 << IDX);
136 case USB::Endpoint::EPNumber::EP0:
137 USBHSD->ENDP_CONFIG |= USBHS_UEP0_T_EN;
139 case USB::Endpoint::EPNumber::EP1:
140 USBHSD->ENDP_CONFIG |= USBHS_UEP1_T_EN;
142 case USB::Endpoint::EPNumber::EP2:
143 USBHSD->ENDP_CONFIG |= USBHS_UEP2_T_EN;
145 case USB::Endpoint::EPNumber::EP3:
146 USBHSD->ENDP_CONFIG |= USBHS_UEP3_T_EN;
148 case USB::Endpoint::EPNumber::EP4:
149 USBHSD->ENDP_CONFIG |= USBHS_UEP4_T_EN;
151 case USB::Endpoint::EPNumber::EP5:
152 USBHSD->ENDP_CONFIG |= USBHS_UEP5_T_EN;
154 case USB::Endpoint::EPNumber::EP6:
155 USBHSD->ENDP_CONFIG |= USBHS_UEP6_T_EN;
157 case USB::Endpoint::EPNumber::EP7:
158 USBHSD->ENDP_CONFIG |= USBHS_UEP7_T_EN;
160 case USB::Endpoint::EPNumber::EP8:
161 USBHSD->ENDP_CONFIG |= USBHS_UEP8_T_EN;
163 case USB::Endpoint::EPNumber::EP9:
164 USBHSD->ENDP_CONFIG |= USBHS_UEP9_T_EN;
166 case USB::Endpoint::EPNumber::EP10:
167 USBHSD->ENDP_CONFIG |= USBHS_UEP10_T_EN;
169 case USB::Endpoint::EPNumber::EP11:
170 USBHSD->ENDP_CONFIG |= USBHS_UEP11_T_EN;
172 case USB::Endpoint::EPNumber::EP12:
173 USBHSD->ENDP_CONFIG |= USBHS_UEP12_T_EN;
175 case USB::Endpoint::EPNumber::EP13:
176 USBHSD->ENDP_CONFIG |= USBHS_UEP13_T_EN;
178 case USB::Endpoint::EPNumber::EP14:
179 USBHSD->ENDP_CONFIG |= USBHS_UEP14_T_EN;
181 case USB::Endpoint::EPNumber::EP15:
182 USBHSD->ENDP_CONFIG |= USBHS_UEP15_T_EN;
193 case USB::Endpoint::EPNumber::EP0:
194 USBHSD->ENDP_CONFIG &= ~USBHS_UEP0_T_EN;
196 case USB::Endpoint::EPNumber::EP1:
197 USBHSD->ENDP_CONFIG &= ~USBHS_UEP1_T_EN;
199 case USB::Endpoint::EPNumber::EP2:
200 USBHSD->ENDP_CONFIG &= ~USBHS_UEP2_T_EN;
202 case USB::Endpoint::EPNumber::EP3:
203 USBHSD->ENDP_CONFIG &= ~USBHS_UEP3_T_EN;
205 case USB::Endpoint::EPNumber::EP4:
206 USBHSD->ENDP_CONFIG &= ~USBHS_UEP4_T_EN;
208 case USB::Endpoint::EPNumber::EP5:
209 USBHSD->ENDP_CONFIG &= ~USBHS_UEP5_T_EN;
211 case USB::Endpoint::EPNumber::EP6:
212 USBHSD->ENDP_CONFIG &= ~USBHS_UEP6_T_EN;
214 case USB::Endpoint::EPNumber::EP7:
215 USBHSD->ENDP_CONFIG &= ~USBHS_UEP7_T_EN;
217 case USB::Endpoint::EPNumber::EP8:
218 USBHSD->ENDP_CONFIG &= ~USBHS_UEP8_T_EN;
220 case USB::Endpoint::EPNumber::EP9:
221 USBHSD->ENDP_CONFIG &= ~USBHS_UEP9_T_EN;
223 case USB::Endpoint::EPNumber::EP10:
224 USBHSD->ENDP_CONFIG &= ~USBHS_UEP10_T_EN;
226 case USB::Endpoint::EPNumber::EP11:
227 USBHSD->ENDP_CONFIG &= ~USBHS_UEP11_T_EN;
229 case USB::Endpoint::EPNumber::EP12:
230 USBHSD->ENDP_CONFIG &= ~USBHS_UEP12_T_EN;
232 case USB::Endpoint::EPNumber::EP13:
233 USBHSD->ENDP_CONFIG &= ~USBHS_UEP13_T_EN;
235 case USB::Endpoint::EPNumber::EP14:
236 USBHSD->ENDP_CONFIG &= ~USBHS_UEP14_T_EN;
238 case USB::Endpoint::EPNumber::EP15:
239 USBHSD->ENDP_CONFIG &= ~USBHS_UEP15_T_EN;
250 case USB::Endpoint::EPNumber::EP0:
251 USBHSD->ENDP_CONFIG |= USBHS_UEP0_R_EN;
253 case USB::Endpoint::EPNumber::EP1:
254 USBHSD->ENDP_CONFIG |= USBHS_UEP1_R_EN;
256 case USB::Endpoint::EPNumber::EP2:
257 USBHSD->ENDP_CONFIG |= USBHS_UEP2_R_EN;
259 case USB::Endpoint::EPNumber::EP3:
260 USBHSD->ENDP_CONFIG |= USBHS_UEP3_R_EN;
262 case USB::Endpoint::EPNumber::EP4:
263 USBHSD->ENDP_CONFIG |= USBHS_UEP4_R_EN;
265 case USB::Endpoint::EPNumber::EP5:
266 USBHSD->ENDP_CONFIG |= USBHS_UEP5_R_EN;
268 case USB::Endpoint::EPNumber::EP6:
269 USBHSD->ENDP_CONFIG |= USBHS_UEP6_R_EN;
271 case USB::Endpoint::EPNumber::EP7:
272 USBHSD->ENDP_CONFIG |= USBHS_UEP7_R_EN;
274 case USB::Endpoint::EPNumber::EP8:
275 USBHSD->ENDP_CONFIG |= USBHS_UEP8_R_EN;
277 case USB::Endpoint::EPNumber::EP9:
278 USBHSD->ENDP_CONFIG |= USBHS_UEP9_R_EN;
280 case USB::Endpoint::EPNumber::EP10:
281 USBHSD->ENDP_CONFIG |= USBHS_UEP10_R_EN;
283 case USB::Endpoint::EPNumber::EP11:
284 USBHSD->ENDP_CONFIG |= USBHS_UEP11_R_EN;
286 case USB::Endpoint::EPNumber::EP12:
287 USBHSD->ENDP_CONFIG |= USBHS_UEP12_R_EN;
289 case USB::Endpoint::EPNumber::EP13:
290 USBHSD->ENDP_CONFIG |= USBHS_UEP13_R_EN;
292 case USB::Endpoint::EPNumber::EP14:
293 USBHSD->ENDP_CONFIG |= USBHS_UEP14_R_EN;
295 case USB::Endpoint::EPNumber::EP15:
296 USBHSD->ENDP_CONFIG |= USBHS_UEP15_R_EN;
307 case USB::Endpoint::EPNumber::EP0:
308 USBHSD->ENDP_CONFIG &= ~USBHS_UEP0_R_EN;
310 case USB::Endpoint::EPNumber::EP1:
311 USBHSD->ENDP_CONFIG &= ~USBHS_UEP1_R_EN;
313 case USB::Endpoint::EPNumber::EP2:
314 USBHSD->ENDP_CONFIG &= ~USBHS_UEP2_R_EN;
316 case USB::Endpoint::EPNumber::EP3:
317 USBHSD->ENDP_CONFIG &= ~USBHS_UEP3_R_EN;
319 case USB::Endpoint::EPNumber::EP4:
320 USBHSD->ENDP_CONFIG &= ~USBHS_UEP4_R_EN;
322 case USB::Endpoint::EPNumber::EP5:
323 USBHSD->ENDP_CONFIG &= ~USBHS_UEP5_R_EN;
325 case USB::Endpoint::EPNumber::EP6:
326 USBHSD->ENDP_CONFIG &= ~USBHS_UEP6_R_EN;
328 case USB::Endpoint::EPNumber::EP7:
329 USBHSD->ENDP_CONFIG &= ~USBHS_UEP7_R_EN;
331 case USB::Endpoint::EPNumber::EP8:
332 USBHSD->ENDP_CONFIG &= ~USBHS_UEP8_R_EN;
334 case USB::Endpoint::EPNumber::EP9:
335 USBHSD->ENDP_CONFIG &= ~USBHS_UEP9_R_EN;
337 case USB::Endpoint::EPNumber::EP10:
338 USBHSD->ENDP_CONFIG &= ~USBHS_UEP10_R_EN;
340 case USB::Endpoint::EPNumber::EP11:
341 USBHSD->ENDP_CONFIG &= ~USBHS_UEP11_R_EN;
343 case USB::Endpoint::EPNumber::EP12:
344 USBHSD->ENDP_CONFIG &= ~USBHS_UEP12_R_EN;
346 case USB::Endpoint::EPNumber::EP13:
347 USBHSD->ENDP_CONFIG &= ~USBHS_UEP13_R_EN;
349 case USB::Endpoint::EPNumber::EP14:
350 USBHSD->ENDP_CONFIG &= ~USBHS_UEP14_R_EN;
352 case USB::Endpoint::EPNumber::EP15:
353 USBHSD->ENDP_CONFIG &= ~USBHS_UEP15_R_EN;
361CH32EndpointOtgHs::CH32EndpointOtgHs(EPNumber ep_num, Direction dir,
363 : Endpoint(ep_num, dir, buffer), hw_double_buffer_(double_buffer), dma_buffer_(buffer)
365 map_otg_hs_[EPNumberToInt8(GetNumber())][
static_cast<uint8_t
>(dir)] =
this;
367 if (dir == Direction::IN)
369 set_tx_dma_buffer(GetNumber(), dma_buffer_.addr_, dma_buffer_.size_, double_buffer);
373 set_rx_dma_buffer(GetNumber(), dma_buffer_.addr_, dma_buffer_.size_, double_buffer);
376 if (dir == Direction::IN)
378 set_tx_len(GetNumber(), 0);
379 *get_tx_control_addr(GetNumber()) = USBHS_UEP_T_RES_NAK;
383 *get_rx_control_addr(GetNumber()) = USBHS_UEP_R_RES_NAK;
387void CH32EndpointOtgHs::Configure(
const Config& cfg)
389 auto& ep_cfg = GetConfig();
392 const int EP_IDX = EPNumberToInt8(GetNumber());
394 const uint8_t IN_IDX =
static_cast<uint8_t
>(Direction::IN);
395 const uint8_t OUT_IDX =
static_cast<uint8_t
>(Direction::OUT);
397 const bool HAS_IN = (map_otg_hs_[EP_IDX][IN_IDX] !=
nullptr);
398 const bool HAS_OUT = (map_otg_hs_[EP_IDX][OUT_IDX] !=
nullptr);
402 bool enable_double = (GetNumber() != EPNumber::EP0) && hw_double_buffer_;
403 if (enable_double && HAS_IN && HAS_OUT)
407 enable_double =
false;
409 ep_cfg.double_buffer = enable_double;
411 const size_t buffer_size = GetBuffer().size_;
412 if (ep_cfg.type == Type::BULK)
416 ASSERT(buffer_size >= 512u);
417 ep_cfg.max_packet_size = 512u;
419 else if (ep_cfg.max_packet_size > buffer_size)
423 ep_cfg.max_packet_size = buffer_size;
426 if (GetDirection() == Direction::IN)
428 if (GetType() != Type::ISOCHRONOUS && GetNumber() != EPNumber::EP0)
430 *get_tx_control_addr(GetNumber()) = USBHS_UEP_T_RES_NAK | USBHS_UEP_T_TOG_AUTO;
434 *get_tx_control_addr(GetNumber()) = USBHS_UEP_T_RES_NAK;
436 set_tx_len(GetNumber(), 0);
440 if (GetType() != Type::ISOCHRONOUS && GetNumber() != EPNumber::EP0)
442 *get_rx_control_addr(GetNumber()) = USBHS_UEP_R_RES_NAK | USBHS_UEP_R_TOG_AUTO;
446 *get_rx_control_addr(GetNumber()) = USBHS_UEP_R_RES_NAK;
449 *get_rx_max_len_addr(GetNumber()) = ep_cfg.max_packet_size;
452 const int IDX =
static_cast<int>(GetNumber());
453 if (GetDirection() == Direction::IN)
455 if (GetType() == Type::ISOCHRONOUS)
457 USBHSD->ENDP_TYPE |= (USBHS_UEP0_T_TYPE << IDX);
461 USBHSD->ENDP_TYPE &= ~(USBHS_UEP0_T_TYPE << IDX);
466 if (GetType() == Type::ISOCHRONOUS)
468 USBHSD->ENDP_TYPE |= (USBHS_UEP0_R_TYPE << IDX);
472 USBHSD->ENDP_TYPE &= ~(USBHS_UEP0_R_TYPE << IDX);
476 if (GetDirection() == Direction::IN)
478 if (GetType() != Type::ISOCHRONOUS)
480 enable_tx(GetNumber());
484 disable_tx(GetNumber());
489 disable_rx(GetNumber());
492 set_tx_dma_buffer(GetNumber(), dma_buffer_.addr_, dma_buffer_.size_, enable_double);
496 enable_rx(GetNumber());
500 disable_tx(GetNumber());
503 set_rx_dma_buffer(GetNumber(), dma_buffer_.addr_, dma_buffer_.size_, enable_double);
506 SetState(State::IDLE);
509void CH32EndpointOtgHs::Close()
511 disable_tx(GetNumber());
512 disable_rx(GetNumber());
514 *get_tx_control_addr(GetNumber()) = USBHS_UEP_T_RES_NAK;
515 *get_rx_control_addr(GetNumber()) = USBHS_UEP_R_RES_NAK;
517 SetState(State::DISABLED);
520ErrorCode CH32EndpointOtgHs::Transfer(
size_t size)
522 if (GetState() == State::BUSY)
524 return ErrorCode::BUSY;
527 auto buffer = GetBuffer();
528 if (buffer.
size_ < size)
530 return ErrorCode::NO_BUFF;
533 bool IS_IN = (GetDirection() == Direction::IN);
535 if (IS_IN && UseDoubleBuffer() && GetType() != Type::ISOCHRONOUS)
540 if (GetNumber() == EPNumber::EP0)
542 if (!IS_IN && size == 0)
549 last_transfer_size_ = size;
550 SetState(State::BUSY);
554 if (GetType() == Type::ISOCHRONOUS)
556 enable_tx(GetNumber());
559 set_tx_len(GetNumber(), size);
560 auto addr = get_tx_control_addr(GetNumber());
562 if (GetType() != Type::ISOCHRONOUS)
564 if (GetNumber() != EPNumber::EP0)
566 *addr = (*addr & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_ACK;
570 *addr = USBHS_UEP_T_RES_ACK |
571 (*addr & (~(USBHS_UEP_T_RES_MASK | USBHS_UEP_T_TOG_MDATA))) |
572 (tog0_ ? USBHS_UEP_T_TOG_DATA1 : 0);
577 *addr = (uint8_t)((*addr & ~(USBHS_UEP_T_RES_MASK | USBHS_UEP_T_TOG_MASK)) |
578 USBHS_UEP_T_TOG_AUTO);
583 auto addr = get_rx_control_addr(GetNumber());
585 if (GetType() != Type::ISOCHRONOUS)
587 if (GetNumber() != EPNumber::EP0)
589 *addr = (*addr & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_ACK;
597 *addr = USBHS_UEP_R_RES_ACK |
598 (*addr & (~(USBHS_UEP_R_RES_MASK | USBHS_UEP_R_TOG_MDATA))) |
599 USBHS_UEP_R_TOG_DATA1;
607 *addr = (*addr & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_ACK;
613 *addr = USBHS_UEP_R_RES_ACK |
614 (*addr & (~(USBHS_UEP_R_RES_MASK | USBHS_UEP_R_TOG_MDATA)));
618 if (GetNumber() == EPNumber::EP0 && IS_IN)
623 return ErrorCode::OK;
628 const bool IS_IN = (GetDirection() == Direction::IN);
629 if (GetState() != State::IDLE && !(GetState() == State::BUSY && !IS_IN))
631 return ErrorCode::BUSY;
636 *get_tx_control_addr(GetNumber()) |= USBHS_UEP_T_RES_STALL;
640 *get_rx_control_addr(GetNumber()) |= USBHS_UEP_R_RES_STALL;
642 SetState(State::STALLED);
643 return ErrorCode::OK;
648 if (GetState() != State::STALLED)
650 return ErrorCode::FAILED;
653 bool IS_IN = (GetDirection() == Direction::IN);
656 *get_tx_control_addr(GetNumber()) &= ~USBHS_UEP_T_RES_STALL;
660 *get_rx_control_addr(GetNumber()) &= ~USBHS_UEP_R_RES_STALL;
662 SetState(State::IDLE);
663 return ErrorCode::OK;
666void CH32EndpointOtgHs::TransferComplete(
size_t size)
668 const bool IS_IN = (GetDirection() == Direction::IN);
669 const bool IS_OUT = !IS_IN;
670 const bool IS_EP0 = (GetNumber() == EPNumber::EP0);
671 const bool IS_ISO = (GetType() == Type::ISOCHRONOUS);
678 auto* tx_ctrl = get_tx_control_addr(GetNumber());
679 *tx_ctrl = (*tx_ctrl & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_NAK;
681 size = last_transfer_size_;
685 set_tx_len(GetNumber(), 0);
686 disable_tx(GetNumber());
695 auto* rx_ctrl = get_rx_control_addr(GetNumber());
696 *rx_ctrl = (*rx_ctrl & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_NAK;
702 if (IS_OUT && !IS_EP0)
705 ((USBHSD->INT_ST & USBHS_UIS_TOG_OK) == USBHS_UIS_TOG_OK);
708 SetState(State::IDLE);
709 (void)Transfer(last_transfer_size_);
714 if (IS_EP0 && IS_OUT)
716 auto* rx_ctrl = get_rx_control_addr(GetNumber());
731 *rx_ctrl =
static_cast<uint8_t
>(
732 ((*rx_ctrl ^ USBHS_UEP_R_TOG_DATA1) & ~USBHS_UEP_R_RES_MASK) |
733 USBHS_UEP_R_RES_NAK);
738 static_cast<uint8_t
>((*rx_ctrl & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_NAK);
741 OnTransferCompleteCallback(
true, size);
744void CH32EndpointOtgHs::SwitchBuffer()
746 if (GetDirection() == Direction::IN)
748 const auto* tx_ctrl = get_tx_control_addr(GetNumber());
749 const bool TOG_IS_DATA1 =
750 ((*tx_ctrl & USBHS_UEP_T_TOG_MASK) == USBHS_UEP_T_TOG_DATA1);
751 SetActiveBlock(!TOG_IS_DATA1);
755 const auto* rx_ctrl = get_rx_control_addr(GetNumber());
756 const bool TOG_IS_DATA1 =
757 ((*rx_ctrl & USBHS_UEP_R_TOG_MASK) == USBHS_UEP_R_TOG_DATA1);
758 SetActiveBlock(TOG_IS_DATA1);
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
EPNumber
端点号 Endpoint number