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;
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);
403 if (enable_double && HAS_IN && HAS_OUT)
407 enable_double =
false;
409 ep_cfg.double_buffer = enable_double;
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;
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;
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());
457 USBHSD->ENDP_TYPE |= (USBHS_UEP0_T_TYPE << IDX);
461 USBHSD->ENDP_TYPE &= ~(USBHS_UEP0_T_TYPE << IDX);
468 USBHSD->ENDP_TYPE |= (USBHS_UEP0_R_TYPE << IDX);
472 USBHSD->ENDP_TYPE &= ~(USBHS_UEP0_R_TYPE << IDX);
514 *get_tx_control_addr(
GetNumber()) = USBHS_UEP_T_RES_NAK;
515 *get_rx_control_addr(
GetNumber()) = USBHS_UEP_R_RES_NAK;
528 if (buffer.
size_ < size)
542 if (!IS_IN && size == 0)
549 last_transfer_size_ = size;
560 auto addr = get_tx_control_addr(
GetNumber());
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());
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)));
636 *get_tx_control_addr(
GetNumber()) |= USBHS_UEP_T_RES_STALL;
640 *get_rx_control_addr(
GetNumber()) |= USBHS_UEP_R_RES_STALL;
656 *get_tx_control_addr(
GetNumber()) &= ~USBHS_UEP_T_RES_STALL;
660 *get_rx_control_addr(
GetNumber()) &= ~USBHS_UEP_R_RES_STALL;
666void CH32EndpointOtgHs::TransferComplete(
size_t size)
669 const bool IS_OUT = !IS_IN;
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_;
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);
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);
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);
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);
void Close() override
关闭端点 / Close endpoint
ErrorCode Stall() override
置 STALL / Stall endpoint
ErrorCode ClearStall() override
清除 STALL / Clear stall
ErrorCode Transfer(size_t size) override
启动一次传输 / Start a transfer
void Configure(const Config &cfg) override
配置端点协议参数 / Configure endpoint protocol parameters
void SwitchBuffer() override
切换双缓冲 / Switch double buffer
可写原始数据视图 / Mutable raw data view
size_t size_
数据字节数 / Data size in bytes
void * addr_
数据起始地址 / Data start address
EPNumber
端点号 Endpoint number
Type GetType() const
获取端点类型 / Get endpoint type
static constexpr uint8_t EPNumberToInt8(EPNumber ep)
端点号转换为 uint8_t / Convert endpoint number to uint8_t
@ OUT
输出方向 / OUT direction
Direction GetDirection() const
获取当前端点方向 / Get current endpoint direction
bool UseDoubleBuffer() const
是否启用双缓冲 / Whether double buffer is enabled
Config & GetConfig()
获取当前配置引用 / Get endpoint config reference
void OnTransferCompleteCallback(bool in_isr, size_t actual_transfer_size)
由底层在传输完成时调用 / Called by low-level driver when transfer completes
@ ISOCHRONOUS
等时端点 / Isochronous
EPNumber GetNumber() const
获取端点号 / Get endpoint number
virtual void SetActiveBlock(bool active_block)
设置当前活动缓冲块 / Set active buffer block
void SetState(State state)
设置端点状态 / Set endpoint state
State GetState() const
获取端点状态 / Get endpoint state
RawData GetBuffer() const
获取当前可用于传输的缓冲区 / Get current transfer buffer
LibXR 命名空间 / LibXR namespace.
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ NO_BUFF
缓冲区不足 / Insufficient buffer
@ FAILED
操作失败 / Operation failed
@ OK
操作成功 / Operation successful