30#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && CFG_TUD_WCH_USBIP_USBHS
52#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir]
55#define EP_TX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_TX_LEN) + (ep) * 2)
56#define EP_TX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_TX_CTRL) + (ep) * 4)
57#define EP_RX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_RX_CTRL) + (ep) * 4)
58#define EP_RX_MAX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_MAX_LEN) + (ep) * 2)
60#define EP_TX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_TX_DMA) + (ep - 1))
61#define EP_RX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_RX_DMA) + (ep - 1))
68 uint8_t response = (response_type ==
EP_RESPONSE_ACK) ? USBHS_EP_T_RES_ACK : USBHS_EP_T_RES_NAK;
71 if (EP_TX_LEN(ep_num) == 0) {
72 EP_TX_CTRL(ep_num) |= USBHS_EP_T_TOG_1;
74 EP_TX_CTRL(ep_num) ^= USBHS_EP_T_TOG_1;
79 EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG;
81 EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response;
84 uint8_t response = (response_type ==
EP_RESPONSE_ACK) ? USBHS_EP_R_RES_ACK : USBHS_EP_R_RES_NAK;
88 EP_RX_CTRL(ep_num) |= USBHS_EP_R_TOG_1;
91 EP_RX_CTRL(ep_num) ^= USBHS_EP_R_TOG_1;
94 EP_RX_CTRL(ep_num) = (EP_RX_CTRL(ep_num) & ~(USBHS_EP_R_RES_MASK)) | response;
101 uint16_t next_tx_size = TU_MIN(remaining,
xfer->max_size);
106 EP_TX_DMA_ADDR(ep_num) = (uint32_t) &
xfer->
buffer[
xfer->queued_len];
109 EP_TX_LEN(ep_num) = next_tx_size;
110 xfer->queued_len += next_tx_size;
112 xfer->is_last_packet =
true;
114 if (
xfer->is_iso ==
true) {
116 USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num);
120 uint16_t max_possible_rx_size = TU_MIN(
xfer->max_size, left_to_receive);
122 if (max_possible_rx_size == left_to_receive) {
123 xfer->is_last_packet =
true;
127 EP_RX_DMA_ADDR(ep_num) = (uint32_t) &
xfer->
buffer[
xfer->queued_len];
128 EP_RX_MAX_LEN(ep_num) = max_possible_rx_size;
131 ep_set_response_and_toggle(ep_num, ep_dir, USBHS_EP_R_RES_ACK);
140 USBHSD->HOST_CTRL = 0x00;
141 USBHSD->HOST_CTRL = USBHS_PHY_SUSPENDM;
145#if TUD_OPT_HIGH_SPEED
146 USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED;
148 #error OPT_MODE_FULL_SPEED not currently supported on CH32
149 USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED;
153 USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_BUS_RST_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN;
155 USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN;
156 USBHSD->ENDP_TYPE = 0x00;
157 USBHSD->BUF_MODE = 0x00;
159 for (
int ep = 0; ep < EP_MAX; ep++) {
161 EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
162 EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK;
164 EP_RX_MAX_LEN(ep) = 0;
167 USBHSD->UEP0_DMA = (uint32_t) ep0_buffer;
168 USBHSD->UEP0_MAX_LEN = CFG_TUD_ENDPOINT0_SIZE;
173 USBHSD->CONTROL |= USBHS_DEV_PU_EN;
180 NVIC_EnableIRQ(USBHS_IRQn);
185 NVIC_DisableIRQ(USBHS_IRQn);
191 for (
size_t ep = 1; ep < EP_MAX; ep++) {
193 EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK;
194 EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK;
196 EP_RX_MAX_LEN(ep) = 0;
199 USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN;
216 USBHSD->INT_EN |= USBHS_SOF_ACT_EN;
218 USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN);
231 EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0;
232 EP_RX_CTRL(0) = USBHS_EP_R_RES_NAK | USBHS_EP_R_TOG_0;
241 TU_ASSERT(ep_num < EP_MAX);
252 USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << ep_num);
253 EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK;
254 if (
xfer->is_iso ==
true) {
255 USBHSD->ENDP_TYPE |= (USBHS_EP0_R_TYP << ep_num);
257 EP_RX_MAX_LEN(ep_num) =
xfer->max_size;
259 if (
xfer->is_iso ==
true) {
260 USBHSD->ENDP_TYPE |= (USBHS_EP0_T_TYP << ep_num);
263 USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num);
265 EP_TX_LEN(ep_num) = 0;
266 EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0;
279 EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK;
280 EP_RX_MAX_LEN(ep_num) = 0;
281 USBHSD->ENDP_TYPE &= ~(USBHS_EP0_R_TYP << ep_num);
282 USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_R_EN << ep_num);
284 EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0;
285 EP_TX_LEN(ep_num) = 0;
286 USBHSD->ENDP_TYPE &= ~(USBHS_EP0_T_TYP << ep_num);
287 USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num);
298 EP_RX_CTRL(ep_num) = USBHS_EP_R_RES_STALL;
301 EP_TX_CTRL(ep_num) = USBHS_EP_T_RES_STALL;
312 EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK;
314 EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_R_RES_NAK;
326 xfer->queued_len = 0;
327 xfer->is_last_packet =
false;
337 uint8_t int_flag = USBHSD->INT_FG;
338 uint8_t int_status = USBHSD->INT_ST;
340 if (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)) {
341 uint8_t
const token = int_status & MASK_UIS_TOKEN;
343 if (token == USBHS_TOKEN_PID_SOF) {
344 uint32_t frame_count = USBHSD->FRAME_NO & USBHS_FRAME_NO_NUM_MASK;
347 uint8_t
const ep_num = int_status & MASK_UIS_ENDP;
352 if (token == USBHS_TOKEN_PID_OUT) {
353 uint16_t rx_len = USBHSD->RX_LEN;
359 xfer->queued_len += rx_len;
360 if (rx_len < xfer->max_size) {
361 xfer->is_last_packet =
true;
363 }
else if (token == USBHS_TOKEN_PID_IN) {
364 if (
xfer->is_iso &&
xfer->is_last_packet) {
366 USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num);
372 if (
xfer->is_last_packet ==
true) {
381 USBHSD->INT_FG = (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG));
382 }
else if (int_flag & USBHS_SETUP_FLAG) {
387 USBHSD->INT_FG = USBHS_SETUP_FLAG;
388 }
else if (int_flag & USBHS_BUS_RST_FLAG) {
411 EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0;
412 EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0;
414 USBHSD->INT_FG = USBHS_BUS_RST_FLAG;
415 }
else if (int_flag & USBHS_SUSPEND_FLAG) {
416 dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_SUSPEND};
419 USBHSD->INT_FG = USBHS_SUSPEND_FLAG;
static TU_ATTR_ALWAYS_INLINE void dcd_event_xfer_complete(uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_setup_received(uint8_t rhport, uint8_t const *setup, bool in_isr)
void dcd_event_handler(dcd_event_t const *event, bool in_isr)
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_reset(uint8_t rhport, tusb_speed_t speed, bool in_isr)
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
static void xfer_data_packet(uint8_t ep_num, tusb_dir_t ep_dir, xfer_ctl_t *xfer)
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
void dcd_int_handler(uint8_t rhport)
static xfer_ctl_t xfer_status[EP_MAX][2]
void dcd_edpt_close_all(uint8_t rhport)
void dcd_int_disable(uint8_t rhport)
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt)
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request)
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
void dcd_int_enable(uint8_t rhport)
void dcd_remote_wakeup(uint8_t rhport)
void dcd_sof_enable(uint8_t rhport, bool en)
xfer_td_t xfer[EP_CBI_COUNT+1][2]
static void * memcpy(void *dst, const void *src, size_t n)
AUDIO Channel Cluster Descriptor (4.1)
struct TU_ATTR_PACKED::@16::TU_ATTR_PACKED bmRequestType_bit
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
uint8_t bRequest
Request type audio_cs_req_t.
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_number(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const *desc_ep)
TU_ATTR_PACKED_END TU_ATTR_BIT_FIELD_ORDER_END static TU_ATTR_ALWAYS_INLINE tusb_dir_t tu_edpt_dir(uint8_t addr)
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)
CFG_TUH_MEM_ALIGN tusb_control_request_t request