6#include "ch32_usb_endpoint.hpp"
7#include "ch32_usbcan_shared.hpp"
12#if defined(RCC_APB1Periph_USB)
15static constexpr uintptr_t REG_BASE = USB_BASE;
17static constexpr uintptr_t REG_BASE = 0x40005C00UL;
21static constexpr uintptr_t PMA_BASE = PMAAddr;
23static constexpr uintptr_t PMA_BASE = 0x40006000UL;
26static inline uintptr_t pma_phys(uint16_t pma_off_bytes)
28 return PMA_BASE + (
static_cast<uintptr_t
>(pma_off_bytes) << 1);
31static inline volatile uint16_t* btable()
33 return reinterpret_cast<volatile uint16_t*
>(REG_BASE + 0x50U);
36static inline volatile uint16_t* ep_reg(uint8_t ep)
38 return reinterpret_cast<volatile uint16_t*
>(REG_BASE +
39 (
static_cast<uintptr_t
>(ep) * 4U));
42#if !defined(USB_EP_CTR_RX) && defined(EP_CTR_RX)
43#define USB_EP_CTR_RX EP_CTR_RX
45#if !defined(USB_EP_DTOG_RX) && defined(EP_DTOG_RX)
46#define USB_EP_DTOG_RX EP_DTOG_RX
48#if !defined(USB_EPRX_STAT) && defined(EPRX_STAT)
49#define USB_EPRX_STAT EPRX_STAT
51#if !defined(USB_EP_SETUP) && defined(EP_SETUP)
52#define USB_EP_SETUP EP_SETUP
54#if !defined(USB_EP_T_FIELD) && defined(EP_T_FIELD)
55#define USB_EP_T_FIELD EP_T_FIELD
57#if !defined(USB_EP_KIND) && defined(EP_KIND)
58#define USB_EP_KIND EP_KIND
60#if !defined(USB_EP_CTR_TX) && defined(EP_CTR_TX)
61#define USB_EP_CTR_TX EP_CTR_TX
63#if !defined(USB_EP_DTOG_TX) && defined(EP_DTOG_TX)
64#define USB_EP_DTOG_TX EP_DTOG_TX
66#if !defined(USB_EPTX_STAT) && defined(EPTX_STAT)
67#define USB_EPTX_STAT EPTX_STAT
69#if !defined(USB_EPADDR_FIELD) && defined(EPADDR_FIELD)
70#define USB_EPADDR_FIELD EPADDR_FIELD
74#define USB_EP_CTR_RX ((uint16_t)0x8000U)
77#define USB_EP_DTOG_RX ((uint16_t)0x4000U)
80#define USB_EPRX_STAT ((uint16_t)0x3000U)
83#define USB_EP_SETUP ((uint16_t)0x0800U)
86#define USB_EP_T_FIELD ((uint16_t)0x0600U)
89#define USB_EP_KIND ((uint16_t)0x0100U)
92#define USB_EP_CTR_TX ((uint16_t)0x0080U)
95#define USB_EP_DTOG_TX ((uint16_t)0x0040U)
98#define USB_EPTX_STAT ((uint16_t)0x0030U)
100#ifndef USB_EPADDR_FIELD
101#define USB_EPADDR_FIELD ((uint16_t)0x000FU)
104#ifndef USB_EP_CONTROL
105#define USB_EP_CONTROL ((uint16_t)0x0200U)
108#define USB_EP_BULK ((uint16_t)0x0000U)
110#ifndef USB_EP_INTERRUPT
111#define USB_EP_INTERRUPT ((uint16_t)0x0600U)
113#ifndef USB_EP_ISOCHRONOUS
114#define USB_EP_ISOCHRONOUS ((uint16_t)0x0400U)
118#define USB_EP_TX_DIS ((uint16_t)0x0000U)
120#ifndef USB_EP_TX_STALL
121#define USB_EP_TX_STALL ((uint16_t)0x0010U)
124#define USB_EP_TX_NAK ((uint16_t)0x0020U)
126#ifndef USB_EP_TX_VALID
127#define USB_EP_TX_VALID ((uint16_t)0x0030U)
131#define USB_EP_RX_DIS ((uint16_t)0x0000U)
133#ifndef USB_EP_RX_STALL
134#define USB_EP_RX_STALL ((uint16_t)0x1000U)
137#define USB_EP_RX_NAK ((uint16_t)0x2000U)
139#ifndef USB_EP_RX_VALID
140#define USB_EP_RX_VALID ((uint16_t)0x3000U)
143#ifndef USB_EPREG_MASK
144#define USB_EPREG_MASK \
145 (USB_EP_CTR_RX | USB_EP_SETUP | USB_EP_T_FIELD | USB_EP_KIND | USB_EP_CTR_TX | \
149#ifndef USB_EPTX_DTOGMASK
150#define USB_EPTX_DTOGMASK (USB_EPTX_STAT | USB_EPREG_MASK)
152#ifndef USB_EPRX_DTOGMASK
153#define USB_EPRX_DTOGMASK (USB_EPRX_STAT | USB_EPREG_MASK)
168static inline volatile BTableEntry* btable_entries()
170 const uint16_t BTABLE_OFF =
static_cast<uint16_t
>((*btable()) & 0xFFF8U);
171 return reinterpret_cast<volatile BTableEntry*
>(pma_phys(BTABLE_OFF));
174static inline void pma_write(uint16_t pma_offset,
const void* src,
size_t len)
176 const uint8_t* s =
reinterpret_cast<const uint8_t*
>(src);
177 volatile uint16_t* p =
reinterpret_cast<volatile uint16_t*
>(pma_phys(pma_offset));
179 for (
size_t i = 0; i < len; i += 2)
184 w |=
static_cast<uint16_t
>(s[i + 1]) << 8;
191static inline void pma_read(
void* dst, uint16_t pma_offset,
size_t len)
193 uint8_t* d =
reinterpret_cast<uint8_t*
>(dst);
194 const volatile uint16_t* p =
195 reinterpret_cast<const volatile uint16_t*
>(pma_phys(pma_offset));
197 for (
size_t i = 0; i < len; i += 2)
199 const uint16_t W = *p;
202 d[i] =
static_cast<uint8_t
>(W & 0xFFU);
205 d[i + 1] =
static_cast<uint8_t
>((W >> 8) & 0xFFU);
210static inline void set_tx_status(uint8_t ep, uint16_t desired_stat)
212 const uint16_t CUR = *ep_reg(ep);
213 uint16_t reg =
static_cast<uint16_t
>(CUR & USB_EPREG_MASK);
216 const uint16_t TARGET =
static_cast<uint16_t
>(desired_stat & USB_EPTX_STAT);
217 reg |=
static_cast<uint16_t
>((CUR ^ TARGET) & USB_EPTX_STAT);
218 reg |=
static_cast<uint16_t
>(USB_EP_CTR_RX | USB_EP_CTR_TX);
222static inline void set_rx_status(uint8_t ep, uint16_t desired_stat)
224 const uint16_t CUR = *ep_reg(ep);
225 uint16_t reg =
static_cast<uint16_t
>(CUR & USB_EPREG_MASK);
228 const uint16_t TARGET =
static_cast<uint16_t
>(desired_stat & USB_EPRX_STAT);
229 reg |=
static_cast<uint16_t
>((CUR ^ TARGET) & USB_EPRX_STAT);
230 reg |=
static_cast<uint16_t
>(USB_EP_CTR_RX | USB_EP_CTR_TX);
234static inline void clear_ctr_tx(uint8_t ep)
236 uint16_t reg =
static_cast<uint16_t
>((*ep_reg(ep)) & USB_EPREG_MASK);
237 reg |=
static_cast<uint16_t
>(USB_EP_CTR_TX | USB_EP_CTR_RX);
238 reg =
static_cast<uint16_t
>(reg & ~USB_EP_CTR_TX);
242static inline void clear_ctr_rx(uint8_t ep)
244 uint16_t reg =
static_cast<uint16_t
>((*ep_reg(ep)) & USB_EPREG_MASK);
245 reg |=
static_cast<uint16_t
>(USB_EP_CTR_TX | USB_EP_CTR_RX);
246 reg =
static_cast<uint16_t
>(reg & ~USB_EP_CTR_RX);
250static inline uint16_t get_rx_count_from_btable(uint8_t ep)
252 return static_cast<uint16_t
>(btable_entries()[ep].count_rx & 0x03FFU);
255static inline uint16_t encode_rx_count(uint16_t mps)
259 const uint16_t BLOCKS =
static_cast<uint16_t
>((mps + 1U) / 2U);
260 return static_cast<uint16_t
>(BLOCKS << 10);
263 const uint16_t BLOCKS =
static_cast<uint16_t
>((mps + 31U) / 32U);
264 return static_cast<uint16_t
>(0x8000U | ((BLOCKS - 1U) << 10));
267static constexpr uint16_t PMA_ALLOC_BASE =
268 static_cast<uint16_t
>(CH32EndpointDevFs::EP_DEV_FS_MAX_SIZE) * 8U;
269static uint16_t g_pma_next = PMA_ALLOC_BASE;
270static uint16_t g_pma_limit = LibXR::CH32UsbCanShared::USBD_PMA_BYTES_SOLO;
272void CH32EndpointDevFs::ResetPMAAllocator()
274 const uint16_t LIMIT_BYTES =
static_cast<uint16_t
>(
275 LibXR::CH32UsbCanShared::usb_pma_limit_bytes() &
static_cast<uint16_t
>(~1U));
276 g_pma_limit = LIMIT_BYTES;
278 g_pma_next = PMA_ALLOC_BASE;
279 g_pma_next =
static_cast<uint16_t
>((g_pma_next + 1U) & ~1U);
280 ASSERT(g_pma_next <= g_pma_limit);
283static inline uint16_t alloc_pma(
size_t bytes)
285 const uint16_t ADDR = g_pma_next;
286 const uint16_t INC =
static_cast<uint16_t
>((bytes + 1U) & ~1U);
288 const uint32_t END =
static_cast<uint32_t
>(ADDR) +
static_cast<uint32_t
>(INC);
289 ASSERT(END <= g_pma_limit);
290 if (END > g_pma_limit)
295 g_pma_next =
static_cast<uint16_t
>(END);
299CH32EndpointDevFs::CH32EndpointDevFs(EPNumber ep_num, Direction dir,
301 : Endpoint(ep_num, dir, buffer), is_isochronous_(is_isochronous)
303 const uint8_t EP_I =
static_cast<uint8_t
>(EPNumberToInt8(GetNumber()));
304 map_dev_fs_[EP_I][
static_cast<uint8_t
>(dir)] =
this;
307void CH32EndpointDevFs::Configure(
const Config& cfg)
309 ASSERT(cfg.direction == Direction::IN || cfg.direction == Direction::OUT);
310 ASSERT(cfg.direction == GetDirection());
312 auto& ep_cfg = GetConfig();
315 const uint8_t EP_I =
static_cast<uint8_t
>(EPNumberToInt8(GetNumber()));
317 size_t packet_size_limit = 64;
318 if (cfg.type == Type::ISOCHRONOUS)
320 packet_size_limit = 1023;
323 const auto BUF = GetBuffer();
324 if (packet_size_limit > BUF.size_)
326 packet_size_limit = BUF.size_;
329 size_t max_packet_size = cfg.max_packet_size;
330 if (max_packet_size > packet_size_limit)
332 max_packet_size = packet_size_limit;
334 if (max_packet_size < 8)
338 if (max_packet_size > BUF.size_)
340 max_packet_size = BUF.size_;
343 ep_cfg.max_packet_size =
static_cast<uint16_t
>(max_packet_size);
345 if (pma_addr_ == 0 || pma_addr_ < PMA_ALLOC_BASE)
347 const uint16_t ADDR = alloc_pma(BUF.size_);
348 ASSERT(ADDR >= PMA_ALLOC_BASE);
349 if (ADDR < PMA_ALLOC_BASE)
356 volatile BTableEntry* bt = btable_entries();
358 if (GetDirection() == Direction::IN)
360 bt[EP_I].addr_tx = pma_addr_;
361 bt[EP_I].count_tx = 0;
365 bt[EP_I].addr_rx = pma_addr_;
366 bt[EP_I].count_rx = encode_rx_count(ep_cfg.max_packet_size);
369 uint16_t epr =
static_cast<uint16_t
>((*ep_reg(EP_I)) & USB_EPREG_MASK);
371 epr =
static_cast<uint16_t
>((epr & ~USB_EPADDR_FIELD) | (EP_I & 0x0FU));
372 epr =
static_cast<uint16_t
>(epr & ~USB_EP_T_FIELD);
377 epr |= USB_EP_CONTROL;
382 case Type::INTERRUPT:
383 epr |= USB_EP_INTERRUPT;
385 case Type::ISOCHRONOUS:
386 epr |= USB_EP_ISOCHRONOUS;
395 if (GetDirection() == Direction::IN)
397 set_tx_status(EP_I, USB_EP_TX_NAK);
401 set_rx_status(EP_I, USB_EP_RX_NAK);
404 SetState(State::IDLE);
407void CH32EndpointDevFs::Close()
409 const uint8_t EP_I =
static_cast<uint8_t
>(EPNumberToInt8(GetNumber()));
410 if (GetDirection() == Direction::IN)
412 set_tx_status(EP_I, USB_EP_TX_DIS);
416 set_rx_status(EP_I, USB_EP_RX_DIS);
420ErrorCode CH32EndpointDevFs::Transfer(
size_t size)
422 if (size > GetBuffer().size_)
424 return ErrorCode::OUT_OF_RANGE;
427 SetState(State::BUSY);
429 const uint8_t EP_I =
static_cast<uint8_t
>(EPNumberToInt8(GetNumber()));
430 last_transfer_size_ = size;
432 if (GetDirection() == Direction::IN)
434 auto buffer = GetBuffer();
435 pma_write(pma_addr_, buffer.
addr_, size);
439 if (UseDoubleBuffer() && size > 0)
441 Endpoint::SwitchBuffer();
444 btable_entries()[EP_I].count_tx =
static_cast<uint16_t
>(size);
445 set_tx_status(EP_I, USB_EP_TX_VALID);
449 volatile BTableEntry* bt = btable_entries();
450 bt[EP_I].addr_rx = pma_addr_;
451 bt[EP_I].count_rx = encode_rx_count(GetConfig().max_packet_size);
452 set_rx_status(EP_I, USB_EP_RX_VALID);
455 return ErrorCode::OK;
458void CH32EndpointDevFs::CopyRxDataToBuffer(
size_t size)
460 if (size > GetBuffer().size_)
462 size = GetBuffer().size_;
464 pma_read(GetBuffer().addr_, pma_addr_, size);
467void CH32EndpointDevFs::TransferComplete(
size_t size)
469 const uint8_t EP_I =
static_cast<uint8_t
>(EPNumberToInt8(GetNumber()));
471 if (GetDirection() == Direction::OUT)
473 const uint16_t RX_CNT = get_rx_count_from_btable(EP_I);
475 if (n > GetBuffer().size_)
477 n = GetBuffer().size_;
479 pma_read(GetBuffer().addr_, pma_addr_, n);
481 set_rx_status(EP_I, USB_EP_RX_NAK);
485 set_tx_status(EP_I, USB_EP_TX_NAK);
486 size = last_transfer_size_;
489 OnTransferCompleteCallback(
true, size);
492ErrorCode CH32EndpointDevFs::Stall()
494 const uint8_t EP_I =
static_cast<uint8_t
>(EPNumberToInt8(GetNumber()));
495 if (GetDirection() == Direction::IN)
497 set_tx_status(EP_I, USB_EP_TX_STALL);
501 set_rx_status(EP_I, USB_EP_RX_STALL);
503 return ErrorCode::OK;
506ErrorCode CH32EndpointDevFs::ClearStall()
508 const uint8_t EP_I =
static_cast<uint8_t
>(EPNumberToInt8(GetNumber()));
509 if (GetDirection() == Direction::IN)
511 set_tx_status(EP_I, USB_EP_TX_NAK);
515 set_rx_status(EP_I, USB_EP_RX_NAK);
517 return ErrorCode::OK;
520void CH32EndpointDevFs::SwitchBuffer() { Endpoint::SwitchBuffer(); }
522void CH32EndpointDevFs::SetEpTxStatus(uint8_t ep, uint16_t status)
524 set_tx_status(ep, status);
526void CH32EndpointDevFs::SetEpRxStatus(uint8_t ep, uint16_t status)
528 set_rx_status(ep, status);
530void CH32EndpointDevFs::ClearEpCtrTx(uint8_t ep) { clear_ctr_tx(ep); }
531void CH32EndpointDevFs::ClearEpCtrRx(uint8_t ep) { clear_ctr_rx(ep); }
532uint16_t CH32EndpointDevFs::GetRxCount(uint8_t ep)
534 return get_rx_count_from_btable(ep);
原始数据封装类。 A class for encapsulating raw data.
void * addr_
数据存储地址。 The storage address of the data.