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);
401 bool enable_double = (GetNumber() != EPNumber::EP0) && hw_double_buffer_;
402 if (enable_double && HAS_IN && HAS_OUT)
405 enable_double =
false;
407 ep_cfg.double_buffer = enable_double;
410 if (ep_cfg.max_packet_size > GetBuffer().size_)
412 ep_cfg.max_packet_size = GetBuffer().size_;
415 if (GetDirection() == Direction::IN)
417 if (GetType() != Type::ISOCHRONOUS && GetNumber() != EPNumber::EP0)
419 *get_tx_control_addr(GetNumber()) = USBHS_UEP_T_RES_NAK | USBHS_UEP_T_TOG_AUTO;
423 *get_tx_control_addr(GetNumber()) = USBHS_UEP_T_RES_NAK;
425 set_tx_len(GetNumber(), 0);
429 if (GetType() != Type::ISOCHRONOUS && GetNumber() != EPNumber::EP0)
431 *get_rx_control_addr(GetNumber()) = USBHS_UEP_R_RES_NAK | USBHS_UEP_R_TOG_AUTO;
435 *get_rx_control_addr(GetNumber()) = USBHS_UEP_R_RES_NAK;
438 if (GetNumber() != EPNumber::EP0)
440 *get_rx_max_len_addr(GetNumber()) = ep_cfg.max_packet_size;
444 const int IDX =
static_cast<int>(GetNumber());
445 if (GetDirection() == Direction::IN)
447 if (GetType() == Type::ISOCHRONOUS)
449 USBHSD->ENDP_TYPE |= (USBHS_UEP0_T_TYPE << IDX);
453 USBHSD->ENDP_TYPE &= ~(USBHS_UEP0_T_TYPE << IDX);
458 if (GetType() == Type::ISOCHRONOUS)
460 USBHSD->ENDP_TYPE |= (USBHS_UEP0_R_TYPE << IDX);
464 USBHSD->ENDP_TYPE &= ~(USBHS_UEP0_R_TYPE << IDX);
468 if (GetDirection() == Direction::IN)
470 if (GetType() != Type::ISOCHRONOUS)
472 enable_tx(GetNumber());
476 disable_tx(GetNumber());
481 disable_rx(GetNumber());
484 set_tx_dma_buffer(GetNumber(), dma_buffer_.addr_, dma_buffer_.size_, enable_double);
488 enable_rx(GetNumber());
492 disable_tx(GetNumber());
495 set_rx_dma_buffer(GetNumber(), dma_buffer_.addr_, dma_buffer_.size_, enable_double);
498 SetState(State::IDLE);
501void CH32EndpointOtgHs::Close()
503 disable_tx(GetNumber());
504 disable_rx(GetNumber());
506 *get_tx_control_addr(GetNumber()) = USBHS_UEP_T_RES_NAK;
507 *get_rx_control_addr(GetNumber()) = USBHS_UEP_R_RES_NAK;
509 SetState(State::DISABLED);
512ErrorCode CH32EndpointOtgHs::Transfer(
size_t size)
514 if (GetState() == State::BUSY)
516 return ErrorCode::BUSY;
519 auto buffer = GetBuffer();
520 if (buffer.
size_ < size)
522 return ErrorCode::NO_BUFF;
525 bool IS_IN = (GetDirection() == Direction::IN);
527 if (IS_IN && UseDoubleBuffer() && GetType() != Type::ISOCHRONOUS)
532 if (GetNumber() == EPNumber::EP0)
541 last_transfer_size_ = size;
542 SetState(State::BUSY);
546 if (GetType() == Type::ISOCHRONOUS)
548 enable_tx(GetNumber());
551 set_tx_len(GetNumber(), size);
552 auto addr = get_tx_control_addr(GetNumber());
554 if (GetType() != Type::ISOCHRONOUS)
556 if (GetNumber() != EPNumber::EP0)
558 *addr = (*addr & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_ACK;
562 *addr = USBHS_UEP_T_RES_ACK |
563 (*addr & (~(USBHS_UEP_T_RES_MASK | USBHS_UEP_T_TOG_MDATA))) |
564 (tog0_ ? USBHS_UEP_T_TOG_DATA1 : 0);
569 *addr = (uint8_t)((*addr & ~(USBHS_UEP_T_RES_MASK | USBHS_UEP_T_TOG_MASK)) |
570 USBHS_UEP_T_TOG_AUTO);
575 auto addr = get_rx_control_addr(GetNumber());
577 if (GetType() != Type::ISOCHRONOUS)
579 if (GetNumber() != EPNumber::EP0)
581 *addr = (*addr & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_ACK;
585 *addr = USBHS_UEP_R_RES_ACK |
586 (*addr & (~(USBHS_UEP_R_RES_MASK | USBHS_UEP_R_TOG_MDATA))) |
587 (tog0_ ? USBHS_UEP_R_TOG_DATA1 : 0);
592 *addr = USBHS_UEP_R_RES_ACK |
593 (*addr & (~(USBHS_UEP_R_RES_MASK | USBHS_UEP_R_TOG_MDATA)));
597 if (GetNumber() == EPNumber::EP0)
602 return ErrorCode::OK;
605ErrorCode CH32EndpointOtgHs::Stall()
607 if (GetState() != State::IDLE)
609 return ErrorCode::BUSY;
612 bool IS_IN = (GetDirection() == Direction::IN);
615 *get_tx_control_addr(GetNumber()) |= USBHS_UEP_T_RES_STALL;
619 *get_rx_control_addr(GetNumber()) |= USBHS_UEP_R_RES_STALL;
621 SetState(State::STALLED);
622 return ErrorCode::OK;
625ErrorCode CH32EndpointOtgHs::ClearStall()
627 if (GetState() != State::STALLED)
629 return ErrorCode::FAILED;
632 bool IS_IN = (GetDirection() == Direction::IN);
635 *get_tx_control_addr(GetNumber()) &= ~USBHS_UEP_T_RES_STALL;
639 *get_rx_control_addr(GetNumber()) &= ~USBHS_UEP_R_RES_STALL;
641 SetState(State::IDLE);
642 return ErrorCode::OK;
645void CH32EndpointOtgHs::TransferComplete(
size_t size)
647 const bool IS_IN = (GetDirection() == Direction::IN);
648 const bool IS_OUT = !IS_IN;
649 const bool IS_EP0 = (GetNumber() == EPNumber::EP0);
650 const bool IS_ISO = (GetType() == Type::ISOCHRONOUS);
656 auto* tx_ctrl = get_tx_control_addr(GetNumber());
657 *tx_ctrl = (*tx_ctrl & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_NAK;
659 size = last_transfer_size_;
663 set_tx_len(GetNumber(), 0);
664 disable_tx(GetNumber());
672 auto* rx_ctrl = get_rx_control_addr(GetNumber());
673 *rx_ctrl = (*rx_ctrl & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_NAK;
681 ((USBHSD->INT_ST & USBHS_UIS_TOG_OK) == USBHS_UIS_TOG_OK);
684 SetState(State::IDLE);
685 (void)Transfer(last_transfer_size_);
690 if (IS_EP0 && IS_OUT)
694 *get_rx_control_addr(GetNumber()) = USBHS_UEP_R_RES_ACK;
697 OnTransferCompleteCallback(
true, size);
700void CH32EndpointOtgHs::SwitchBuffer()
702 if (GetDirection() == Direction::IN)
704 const auto* tx_ctrl = get_tx_control_addr(GetNumber());
705 const bool TOG_IS_DATA1 =
706 ((*tx_ctrl & USBHS_UEP_T_TOG_MASK) == USBHS_UEP_T_TOG_DATA1);
707 SetActiveBlock(!TOG_IS_DATA1);
711 const auto* rx_ctrl = get_rx_control_addr(GetNumber());
712 const bool TOG_IS_DATA1 =
713 ((*rx_ctrl & USBHS_UEP_R_TOG_MASK) == USBHS_UEP_R_TOG_DATA1);
714 SetActiveBlock(TOG_IS_DATA1);
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
EPNumber
端点号 Endpoint number