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);
36 return reinterpret_cast<volatile uint16_t*
>(
37 reinterpret_cast<volatile uint8_t*
>(&USBHSD->UEP0_MAX_LEN) +
38 static_cast<int>(ep_num) * 2);
43 if (ep_num == USB::Endpoint::EPNumber::EP0)
return &USBHSD->UEP0_DMA;
44 return reinterpret_cast<volatile uint32_t*
>(
45 reinterpret_cast<volatile uint32_t*
>(&USBHSD->UEP1_TX_DMA) +
46 (
static_cast<int>(ep_num) - 1));
51 if (ep_num == USB::Endpoint::EPNumber::EP0)
return &USBHSD->UEP0_DMA;
52 return reinterpret_cast<volatile uint32_t*
>(
53 reinterpret_cast<volatile uint32_t*
>(&USBHSD->UEP1_RX_DMA) +
54 (
static_cast<int>(ep_num) - 1));
59 *GetTxLenAddr(ep_num) = value;
63 uint32_t buffer_size,
bool double_buffer)
65 uint8_t* buf_base =
reinterpret_cast<uint8_t*
>(buffer);
66 uint8_t* buf_alt = buf_base + buffer_size / 2;
68 if (ep_num == USB::Endpoint::EPNumber::EP0)
70 USBHSD->UEP0_DMA = (uint32_t)buf_base;
74 *GetTxDmaAddr(ep_num) = (uint32_t)buf_base;
75 if (double_buffer) *GetRxDmaAddr(ep_num) = (uint32_t)buf_alt;
78 int idx =
static_cast<int>(ep_num);
79 if (double_buffer && ep_num != USB::Endpoint::EPNumber::EP0)
80 USBHSD->BUF_MODE |= (1 << idx);
82 USBHSD->BUF_MODE &= ~(1 << idx);
86 uint32_t buffer_size,
bool double_buffer)
88 uint8_t* buf_base =
reinterpret_cast<uint8_t*
>(buffer);
89 uint8_t* buf_alt = buf_base + buffer_size / 2;
91 if (ep_num == USB::Endpoint::EPNumber::EP0)
93 USBHSD->UEP0_DMA = (uint32_t)buf_base;
97 *GetRxDmaAddr(ep_num) = (uint32_t)buf_base;
98 if (double_buffer) *GetTxDmaAddr(ep_num) = (uint32_t)buf_alt;
101 int idx =
static_cast<int>(ep_num);
102 if (double_buffer && ep_num != USB::Endpoint::EPNumber::EP0)
103 USBHSD->BUF_MODE |= (1 << idx);
105 USBHSD->BUF_MODE &= ~(1 << idx);
112 case USB::Endpoint::EPNumber::EP0:
113 USBHSD->ENDP_CONFIG |= USBHS_UEP0_T_EN;
115 case USB::Endpoint::EPNumber::EP1:
116 USBHSD->ENDP_CONFIG |= USBHS_UEP1_T_EN;
118 case USB::Endpoint::EPNumber::EP2:
119 USBHSD->ENDP_CONFIG |= USBHS_UEP2_T_EN;
121 case USB::Endpoint::EPNumber::EP3:
122 USBHSD->ENDP_CONFIG |= USBHS_UEP3_T_EN;
124 case USB::Endpoint::EPNumber::EP4:
125 USBHSD->ENDP_CONFIG |= USBHS_UEP4_T_EN;
127 case USB::Endpoint::EPNumber::EP5:
128 USBHSD->ENDP_CONFIG |= USBHS_UEP5_T_EN;
130 case USB::Endpoint::EPNumber::EP6:
131 USBHSD->ENDP_CONFIG |= USBHS_UEP6_T_EN;
133 case USB::Endpoint::EPNumber::EP7:
134 USBHSD->ENDP_CONFIG |= USBHS_UEP7_T_EN;
136 case USB::Endpoint::EPNumber::EP8:
137 USBHSD->ENDP_CONFIG |= USBHS_UEP8_T_EN;
139 case USB::Endpoint::EPNumber::EP9:
140 USBHSD->ENDP_CONFIG |= USBHS_UEP9_T_EN;
142 case USB::Endpoint::EPNumber::EP10:
143 USBHSD->ENDP_CONFIG |= USBHS_UEP10_T_EN;
145 case USB::Endpoint::EPNumber::EP11:
146 USBHSD->ENDP_CONFIG |= USBHS_UEP11_T_EN;
148 case USB::Endpoint::EPNumber::EP12:
149 USBHSD->ENDP_CONFIG |= USBHS_UEP12_T_EN;
151 case USB::Endpoint::EPNumber::EP13:
152 USBHSD->ENDP_CONFIG |= USBHS_UEP13_T_EN;
154 case USB::Endpoint::EPNumber::EP14:
155 USBHSD->ENDP_CONFIG |= USBHS_UEP14_T_EN;
157 case USB::Endpoint::EPNumber::EP15:
158 USBHSD->ENDP_CONFIG |= USBHS_UEP15_T_EN;
169 case USB::Endpoint::EPNumber::EP0:
170 USBHSD->ENDP_CONFIG &= ~USBHS_UEP0_T_EN;
172 case USB::Endpoint::EPNumber::EP1:
173 USBHSD->ENDP_CONFIG &= ~USBHS_UEP1_T_EN;
175 case USB::Endpoint::EPNumber::EP2:
176 USBHSD->ENDP_CONFIG &= ~USBHS_UEP2_T_EN;
178 case USB::Endpoint::EPNumber::EP3:
179 USBHSD->ENDP_CONFIG &= ~USBHS_UEP3_T_EN;
181 case USB::Endpoint::EPNumber::EP4:
182 USBHSD->ENDP_CONFIG &= ~USBHS_UEP4_T_EN;
184 case USB::Endpoint::EPNumber::EP5:
185 USBHSD->ENDP_CONFIG &= ~USBHS_UEP5_T_EN;
187 case USB::Endpoint::EPNumber::EP6:
188 USBHSD->ENDP_CONFIG &= ~USBHS_UEP6_T_EN;
190 case USB::Endpoint::EPNumber::EP7:
191 USBHSD->ENDP_CONFIG &= ~USBHS_UEP7_T_EN;
193 case USB::Endpoint::EPNumber::EP8:
194 USBHSD->ENDP_CONFIG &= ~USBHS_UEP8_T_EN;
196 case USB::Endpoint::EPNumber::EP9:
197 USBHSD->ENDP_CONFIG &= ~USBHS_UEP9_T_EN;
199 case USB::Endpoint::EPNumber::EP10:
200 USBHSD->ENDP_CONFIG &= ~USBHS_UEP10_T_EN;
202 case USB::Endpoint::EPNumber::EP11:
203 USBHSD->ENDP_CONFIG &= ~USBHS_UEP11_T_EN;
205 case USB::Endpoint::EPNumber::EP12:
206 USBHSD->ENDP_CONFIG &= ~USBHS_UEP12_T_EN;
208 case USB::Endpoint::EPNumber::EP13:
209 USBHSD->ENDP_CONFIG &= ~USBHS_UEP13_T_EN;
211 case USB::Endpoint::EPNumber::EP14:
212 USBHSD->ENDP_CONFIG &= ~USBHS_UEP14_T_EN;
214 case USB::Endpoint::EPNumber::EP15:
215 USBHSD->ENDP_CONFIG &= ~USBHS_UEP15_T_EN;
226 case USB::Endpoint::EPNumber::EP0:
227 USBHSD->ENDP_CONFIG |= USBHS_UEP0_R_EN;
229 case USB::Endpoint::EPNumber::EP1:
230 USBHSD->ENDP_CONFIG |= USBHS_UEP1_R_EN;
232 case USB::Endpoint::EPNumber::EP2:
233 USBHSD->ENDP_CONFIG |= USBHS_UEP2_R_EN;
235 case USB::Endpoint::EPNumber::EP3:
236 USBHSD->ENDP_CONFIG |= USBHS_UEP3_R_EN;
238 case USB::Endpoint::EPNumber::EP4:
239 USBHSD->ENDP_CONFIG |= USBHS_UEP4_R_EN;
241 case USB::Endpoint::EPNumber::EP5:
242 USBHSD->ENDP_CONFIG |= USBHS_UEP5_R_EN;
244 case USB::Endpoint::EPNumber::EP6:
245 USBHSD->ENDP_CONFIG |= USBHS_UEP6_R_EN;
247 case USB::Endpoint::EPNumber::EP7:
248 USBHSD->ENDP_CONFIG |= USBHS_UEP7_R_EN;
250 case USB::Endpoint::EPNumber::EP8:
251 USBHSD->ENDP_CONFIG |= USBHS_UEP8_R_EN;
253 case USB::Endpoint::EPNumber::EP9:
254 USBHSD->ENDP_CONFIG |= USBHS_UEP9_R_EN;
256 case USB::Endpoint::EPNumber::EP10:
257 USBHSD->ENDP_CONFIG |= USBHS_UEP10_R_EN;
259 case USB::Endpoint::EPNumber::EP11:
260 USBHSD->ENDP_CONFIG |= USBHS_UEP11_R_EN;
262 case USB::Endpoint::EPNumber::EP12:
263 USBHSD->ENDP_CONFIG |= USBHS_UEP12_R_EN;
265 case USB::Endpoint::EPNumber::EP13:
266 USBHSD->ENDP_CONFIG |= USBHS_UEP13_R_EN;
268 case USB::Endpoint::EPNumber::EP14:
269 USBHSD->ENDP_CONFIG |= USBHS_UEP14_R_EN;
271 case USB::Endpoint::EPNumber::EP15:
272 USBHSD->ENDP_CONFIG |= USBHS_UEP15_R_EN;
283 case USB::Endpoint::EPNumber::EP0:
284 USBHSD->ENDP_CONFIG &= ~USBHS_UEP0_R_EN;
286 case USB::Endpoint::EPNumber::EP1:
287 USBHSD->ENDP_CONFIG &= ~USBHS_UEP1_R_EN;
289 case USB::Endpoint::EPNumber::EP2:
290 USBHSD->ENDP_CONFIG &= ~USBHS_UEP2_R_EN;
292 case USB::Endpoint::EPNumber::EP3:
293 USBHSD->ENDP_CONFIG &= ~USBHS_UEP3_R_EN;
295 case USB::Endpoint::EPNumber::EP4:
296 USBHSD->ENDP_CONFIG &= ~USBHS_UEP4_R_EN;
298 case USB::Endpoint::EPNumber::EP5:
299 USBHSD->ENDP_CONFIG &= ~USBHS_UEP5_R_EN;
301 case USB::Endpoint::EPNumber::EP6:
302 USBHSD->ENDP_CONFIG &= ~USBHS_UEP6_R_EN;
304 case USB::Endpoint::EPNumber::EP7:
305 USBHSD->ENDP_CONFIG &= ~USBHS_UEP7_R_EN;
307 case USB::Endpoint::EPNumber::EP8:
308 USBHSD->ENDP_CONFIG &= ~USBHS_UEP8_R_EN;
310 case USB::Endpoint::EPNumber::EP9:
311 USBHSD->ENDP_CONFIG &= ~USBHS_UEP9_R_EN;
313 case USB::Endpoint::EPNumber::EP10:
314 USBHSD->ENDP_CONFIG &= ~USBHS_UEP10_R_EN;
316 case USB::Endpoint::EPNumber::EP11:
317 USBHSD->ENDP_CONFIG &= ~USBHS_UEP11_R_EN;
319 case USB::Endpoint::EPNumber::EP12:
320 USBHSD->ENDP_CONFIG &= ~USBHS_UEP12_R_EN;
322 case USB::Endpoint::EPNumber::EP13:
323 USBHSD->ENDP_CONFIG &= ~USBHS_UEP13_R_EN;
325 case USB::Endpoint::EPNumber::EP14:
326 USBHSD->ENDP_CONFIG &= ~USBHS_UEP14_R_EN;
328 case USB::Endpoint::EPNumber::EP15:
329 USBHSD->ENDP_CONFIG &= ~USBHS_UEP15_R_EN;
337CH32EndpointOtgHs::CH32EndpointOtgHs(EPNumber ep_num, Direction dir,
339 : Endpoint(ep_num, dir, buffer), hw_double_buffer_(double_buffer), dma_buffer_(buffer)
341 map_otg_hs_[EPNumberToInt8(GetNumber())][
static_cast<uint8_t
>(dir)] =
this;
343 if (dir == Direction::IN)
345 SetTxDmaBuffer(GetNumber(), dma_buffer_.addr_, dma_buffer_.size_, double_buffer);
349 SetRxDmaBuffer(GetNumber(), dma_buffer_.addr_, dma_buffer_.size_, double_buffer);
352 if (dir == Direction::IN)
354 SetTxLen(GetNumber(), 0);
355 *GetTxControlAddr(GetNumber()) = USBHS_UEP_T_RES_NAK;
359 *GetRxControlAddr(GetNumber()) = USBHS_UEP_R_RES_NAK;
363void CH32EndpointOtgHs::Configure(
const Config& cfg)
365 auto& ep_cfg = GetConfig();
368 if (GetNumber() != EPNumber::EP0 && hw_double_buffer_)
370 ep_cfg.double_buffer =
true;
374 if (ep_cfg.double_buffer)
378 ep_cfg.double_buffer =
false;
381 if (ep_cfg.max_packet_size > GetBuffer().size_)
383 ep_cfg.max_packet_size = GetBuffer().size_;
386 *GetRxControlAddr(GetNumber()) = USBHS_UEP_R_RES_NAK;
387 *GetTxControlAddr(GetNumber()) = USBHS_UEP_T_RES_NAK;
389 SetTxLen(GetNumber(), 0);
392 const int idx =
static_cast<int>(GetNumber());
393 if (GetDirection() == Direction::IN)
395 if (GetType() == Type::ISOCHRONOUS)
396 USBHSD->ENDP_TYPE |= (USBHS_UEP0_T_TYPE << idx);
398 USBHSD->ENDP_TYPE &= ~(USBHS_UEP0_T_TYPE << idx);
402 if (GetType() == Type::ISOCHRONOUS)
403 USBHSD->ENDP_TYPE |= (USBHS_UEP0_R_TYPE << idx);
405 USBHSD->ENDP_TYPE &= ~(USBHS_UEP0_R_TYPE << idx);
409 if (GetDirection() == Direction::IN)
411 if (GetType() != Type::ISOCHRONOUS)
413 EnableTx(GetNumber());
417 DisableTx(GetNumber());
419 DisableRx(GetNumber());
420 SetTxDmaBuffer(GetNumber(), dma_buffer_.addr_, dma_buffer_.size_, hw_double_buffer_);
424 DisableTx(GetNumber());
425 EnableRx(GetNumber());
426 SetRxDmaBuffer(GetNumber(), dma_buffer_.addr_, dma_buffer_.size_, hw_double_buffer_);
428 if (GetType() == Type::ISOCHRONOUS)
430 *GetRxMaxLenAddr(GetNumber()) = ep_cfg.max_packet_size;
434 SetState(State::IDLE);
437void CH32EndpointOtgHs::Close()
439 DisableTx(GetNumber());
440 DisableRx(GetNumber());
442 *GetTxControlAddr(GetNumber()) = USBHS_UEP_T_RES_NAK;
443 *GetRxControlAddr(GetNumber()) = USBHS_UEP_R_RES_NAK;
445 SetState(State::DISABLED);
448ErrorCode CH32EndpointOtgHs::Transfer(
size_t size)
450 if (GetState() == State::BUSY)
452 return ErrorCode::BUSY;
455 auto buffer = GetBuffer();
456 if (buffer.
size_ < size)
458 return ErrorCode::NO_BUFF;
461 bool is_in = (GetDirection() == Direction::IN);
463 if (is_in && UseDoubleBuffer() && GetType() != Type::ISOCHRONOUS)
468 if (GetNumber() == EPNumber::EP0)
477 last_transfer_size_ = size;
478 SetState(State::BUSY);
482 if (GetType() == Type::ISOCHRONOUS)
484 EnableTx(GetNumber());
487 SetTxLen(GetNumber(), size);
488 auto addr = GetTxControlAddr(GetNumber());
490 if (GetType() != Type::ISOCHRONOUS)
492 *addr = USBHS_UEP_T_RES_ACK |
493 (*addr & (~(USBHS_UEP_T_RES_MASK | USBHS_UEP_T_TOG_MDATA))) |
494 (tog0_ ? USBHS_UEP_T_TOG_DATA1 : 0);
498 *addr = (uint8_t)((*addr & ~(USBHS_UEP_T_RES_MASK | USBHS_UEP_T_TOG_MASK)) |
499 USBHS_UEP_T_TOG_AUTO);
504 auto addr = GetRxControlAddr(GetNumber());
506 if (GetType() != Type::ISOCHRONOUS)
508 *addr = USBHS_UEP_R_RES_ACK |
509 (*addr & (~(USBHS_UEP_R_RES_MASK | USBHS_UEP_R_TOG_MDATA))) |
510 (tog0_ ? USBHS_UEP_R_TOG_DATA1 : 0);
514 *addr = USBHS_UEP_R_RES_ACK |
515 (*addr & (~(USBHS_UEP_R_RES_MASK | USBHS_UEP_R_TOG_MDATA)));
519 if (GetNumber() == EPNumber::EP0)
524 return ErrorCode::OK;
527ErrorCode CH32EndpointOtgHs::Stall()
529 if (GetState() != State::IDLE)
531 return ErrorCode::BUSY;
534 bool is_in = (GetDirection() == Direction::IN);
537 *GetTxControlAddr(GetNumber()) |= USBHS_UEP_T_RES_STALL;
541 *GetRxControlAddr(GetNumber()) |= USBHS_UEP_R_RES_STALL;
543 SetState(State::STALLED);
544 return ErrorCode::OK;
547ErrorCode CH32EndpointOtgHs::ClearStall()
549 if (GetState() != State::STALLED)
551 return ErrorCode::FAILED;
554 bool is_in = (GetDirection() == Direction::IN);
557 *GetTxControlAddr(GetNumber()) &= ~USBHS_UEP_T_RES_STALL;
561 *GetRxControlAddr(GetNumber()) &= ~USBHS_UEP_R_RES_STALL;
563 SetState(State::IDLE);
564 return ErrorCode::OK;
567void CH32EndpointOtgHs::TransferComplete(
size_t size)
569 if (GetState() == State::BUSY && GetNumber() != EPNumber::EP0 &&
570 GetType() != Type::ISOCHRONOUS)
575 if (GetDirection() == Direction::IN)
577 *GetTxControlAddr(GetNumber()) =
578 (*GetTxControlAddr(GetNumber()) & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_NAK;
580 USBHSD->INT_FG = USBHS_UIF_ISO_ACT | USBHS_UIF_TRANSFER;
582 size = last_transfer_size_;
584 if (GetType() == Type::ISOCHRONOUS)
586 SetTxLen(GetNumber(), 0);
587 DisableTx(GetNumber());
591 if (GetDirection() == Direction::OUT &&
592 (USBHSD->INT_ST & USBHS_UIS_TOG_OK) != USBHS_UIS_TOG_OK)
597 if (GetNumber() == EPNumber::EP0 && GetDirection() == Direction::OUT)
601 *GetRxControlAddr(GetNumber()) = USBHS_UEP_R_RES_ACK;
604 OnTransferCompleteCallback(
true, size);
607void CH32EndpointOtgHs::SwitchBuffer()
609 if (GetDirection() == Direction::IN)
611 SetActiveBlock(!tog0_);
615 SetActiveBlock(tog0_);
原始数据封装类。 A class for encapsulating raw data.
size_t size_
数据大小(字节)。 The size of the data (in bytes).
EPNumber
端点号 / Endpoint number