From bd9dd75da8718dfd56b2e91b658f81613ed1bf3a Mon Sep 17 00:00:00 2001 From: Mitsumine Suzu <60875431+verylowfreq@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:26:08 +0900 Subject: [PATCH 1/5] Small cleanups. --- src/portable/wch/hcd_ch32_usbfs.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c index d176f40c5..fc52597c2 100644 --- a/src/portable/wch/hcd_ch32_usbfs.c +++ b/src/portable/wch/hcd_ch32_usbfs.c @@ -120,9 +120,6 @@ static usb_edpt_t *get_empty_record_slot(void) { static usb_edpt_t *add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type) { usb_edpt_t *slot = get_empty_record_slot(); - if (slot == NULL) { - PANIC("add_edpt_record(0x%02x, 0x%02x, ...) no slot for new record\r\n", dev_addr, ep_addr); - } TU_ASSERT(slot != NULL, NULL); slot->dev_addr = dev_addr; @@ -412,10 +409,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { } else { LOG_CH32_USBFSH("USB_PID_OUT continue...\r\n"); usb_current_xfer_info.buffer += tx_len; - uint16_t copylen = USBFS_TX_BUF_LEN; - if (copylen > usb_current_xfer_info.bufferlen) { - copylen = usb_current_xfer_info.bufferlen; - } + uint16_t copylen = TU_MIN(edpt_info->max_packet_size, usb_current_xfer_info.bufferlen); memcpy(USBFS_TX_Buf, usb_current_xfer_info.buffer, copylen); hardware_start_xfer(USB_PID_OUT, ep_addr, edpt_info->data_toggle); return; @@ -445,7 +439,10 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { } } default: { - PANIC("Unknown PID: 0x%02x\n", request_pid); + LOG_CH32_USBFSH("hcd_int_handler() L%d: unexpected response PID: 0x%02x\r\n", __LINE__, response_pid); + usb_current_xfer_info.is_busy = false; + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); + return; } } } else { @@ -474,7 +471,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); return; } else { - LOG_CH32_USBFSH("In USBHD_IRQHandler, unexpected response PID: 0x%02x\r\n", response_pid); + LOG_CH32_USBFSH("hcd_int_handler() L%d: unexpected response PID: 0x%02x\r\n", __LINE__, response_pid); usb_current_xfer_info.is_busy = false; hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); return; @@ -519,9 +516,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b usb_current_xfer_info.is_busy = true; usb_edpt_t *edpt_info = get_edpt_record(dev_addr, ep_addr); - if (edpt_info == NULL) { - PANIC("get_edpt_record() returned NULL in hcd_edpt_xfer()\r\n"); - } + TU_ASSERT(edpt_info != NULL); hardware_set_port_address_speed(dev_addr); @@ -537,10 +532,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b return hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle); } else { LOG_CH32_USBFSH("hcd_edpt_xfer(): WRITE, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen); - uint16_t copylen = USBFS_TX_BUF_LEN; - if (copylen > buflen) { - copylen = buflen; - } + uint16_t copylen = TU_MIN(edpt_info->max_packet_size, buflen); USBOTG_H_FS->HOST_TX_LEN = copylen; memcpy(USBFS_TX_Buf, buffer, copylen); return hardware_start_xfer(USB_PID_OUT, ep_addr, edpt_info->data_toggle); @@ -596,7 +588,6 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; LOG_CH32_USBFSH("hcd_edpt_clear_stall(rhport=%d, dev_addr=0x%02x, ep_addr=0x%02x)\r\n", rhport, dev_addr, ep_addr); - // PANIC("\r\install\r\n"); uint8_t edpt_num = tu_edpt_number(ep_addr); uint8_t setup_request_clear_stall[8] = { 0x02, 0x01, 0x00, 0x00, edpt_num, 0x00, 0x00, 0x00 From 522a34ee28bcee6674ccd91973cb87869be98909 Mon Sep 17 00:00:00 2001 From: Mitsumine Suzu <60875431+verylowfreq@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:28:32 +0900 Subject: [PATCH 2/5] Insert small delay for LowSpeed device --- src/portable/wch/hcd_ch32_usbfs.c | 35 +++++++++++++++++-------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c index fc52597c2..38bb0ed59 100644 --- a/src/portable/wch/hcd_ch32_usbfs.c +++ b/src/portable/wch/hcd_ch32_usbfs.c @@ -55,18 +55,18 @@ TU_ATTR_ALIGNED(4) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN]; #define LOG_CH32_USBFSH(...) TU_LOG3(__VA_ARGS__) // Busywait for delay microseconds/nanoseconds -// static void loopdelay(uint32_t count) -// { -// volatile uint32_t c = count / 3; -// if (c == 0) { return; } -// // while (c-- != 0); -// asm volatile( -// "1: \n" // loop label -// " addi %0, %0, -1 \n" // c-- -// " bne %0, zero, 1b \n" // if (c != 0) goto loop -// : "+r"(c) // c is input/output operand -// ); -// } +static void loopdelay(uint32_t count) +{ + volatile uint32_t c = count / 3; + if (c == 0) { return; } + // while (c-- != 0); + asm volatile( + "1: \n" // loop label + " addi %0, %0, -1 \n" // c-- + " bne %0, zero, 1b \n" // if (c != 0) goto loop + : "+r"(c) // c is input/output operand + ); +} // Endpoint status @@ -194,10 +194,13 @@ static bool hardware_start_xfer(uint8_t pid, uint8_t ep_addr, uint8_t data_toggl : "(other)", pid, ep_addr, data_toggle); - // if (pid == USB_PID_IN) - // { // FIXME: long delay needed (at release build) about 30msec - // loopdelay(SystemCoreClock / 1000 * 30); - // } + //WORKAROUND: For LowSpeed device, insert small delay + bool is_lowspeed_device = tuh_speed_get(usb_current_xfer_info.dev_addr) == TUSB_SPEED_LOW; + if (is_lowspeed_device) { + //NOTE: worked -> SystemCoreClock / 1000000 * 50, 25 + // NOT worked -> 20 and less (at 144MHz internal clock) + loopdelay(SystemCoreClock / 1000000 * 40); + } uint8_t pid_edpt = (pid << 4) | (tu_edpt_number(ep_addr) & 0x0f); USBOTG_H_FS->HOST_TX_CTRL = (data_toggle != 0) ? USBFS_UH_T_TOG : 0; From a3bb7a90b3478f43d448443140b68c3473331f93 Mon Sep 17 00:00:00 2001 From: Mitsumine Suzu <60875431+verylowfreq@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:46:12 +0900 Subject: [PATCH 3/5] Improve retry operation at NAK response. --- src/portable/wch/hcd_ch32_usbfs.c | 76 +++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 10 deletions(-) diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c index 38bb0ed59..449908658 100644 --- a/src/portable/wch/hcd_ch32_usbfs.c +++ b/src/portable/wch/hcd_ch32_usbfs.c @@ -28,6 +28,8 @@ #if CFG_TUH_ENABLED && defined(TUP_USBIP_WCH_USBFS) && defined(CFG_TUH_WCH_USBIP_USBFS) && CFG_TUH_WCH_USBIP_USBFS +#include + #include "host/hcd.h" #include "host/usbh.h" #include "host/usbh_pvt.h" @@ -95,6 +97,7 @@ typedef struct usb_current_xfer_st { uint8_t *buffer; uint16_t bufferlen; uint16_t xferred_len; + bool nak_pending; } usb_current_xfer_t; static volatile usb_current_xfer_t usb_current_xfer_info = {}; @@ -351,6 +354,34 @@ void hcd_int_disable(uint8_t rhport) { interrupt_enabled = false; } +typedef struct { + uint8_t rhport; + uint8_t dev_addr; + uint8_t ep_addr; + uint16_t buflen; + uint8_t* buf; +} xfer_retry_param_t; + +static void xfer_retry(void* _params) { + LOG_CH32_USBFSH("xfer_retry()\r\n"); + xfer_retry_param_t* params = (xfer_retry_param_t*)_params; + if (usb_current_xfer_info.nak_pending) { + usb_current_xfer_info.nak_pending = false; + + uint8_t dev_addr = params->dev_addr; + uint8_t ep_addr = params->ep_addr; + uint16_t buflen = params->buflen; + uint8_t* buf = params->buf; + free(params); + + usb_edpt_t* edpt_info = get_edpt_record(dev_addr, ep_addr); + if (edpt_info) { + hcd_edpt_xfer(0, dev_addr, ep_addr, buf, buflen); + } + } +} + + void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) rhport; (void) in_isr; @@ -407,7 +438,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { if (usb_current_xfer_info.bufferlen == 0) { LOG_CH32_USBFSH("USB_PID_%s completed %d bytes\r\n", request_pid == USB_PID_OUT ? "OUT" : "SETUP", usb_current_xfer_info.xferred_len); usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, usb_current_xfer_info.xferred_len, XFER_RESULT_SUCCESS, true); + hcd_event_xfer_complete(dev_addr, ep_addr, usb_current_xfer_info.xferred_len, XFER_RESULT_SUCCESS, in_isr); return; } else { LOG_CH32_USBFSH("USB_PID_OUT continue...\r\n"); @@ -432,7 +463,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // USB device sent all data. LOG_CH32_USBFSH("USB_PID_IN completed\r\n"); usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, XFER_RESULT_SUCCESS, true); + hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, XFER_RESULT_SUCCESS, in_isr); return; } else { // USB device may send more data. @@ -444,7 +475,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { default: { LOG_CH32_USBFSH("hcd_int_handler() L%d: unexpected response PID: 0x%02x\r\n", __LINE__, response_pid); usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, in_isr); return; } } @@ -458,25 +489,46 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { } else if (response_pid == USB_PID_NAK) { LOG_CH32_USBFSH("NAK reposense\r\n"); uint32_t elapsed_time = board_millis() - usb_current_xfer_info.start_ms; + (void)elapsed_time; if (edpt_info->xfer_type == TUSB_XFER_INTERRUPT) { usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, true); - } else if (elapsed_time > USB_XFER_TIMEOUT_MILLIS) { - usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, in_isr); + } else { - hardware_start_xfer(request_pid, ep_addr, edpt_info->data_toggle); + usb_current_xfer_info.is_busy = false; + usb_current_xfer_info.nak_pending = true; + + xfer_retry_param_t* param_buf = malloc(sizeof(xfer_retry_param_t)); + xfer_retry_param_t param = { + .rhport = 0, + .dev_addr = dev_addr, + .ep_addr = ep_addr, + .buflen = usb_current_xfer_info.bufferlen, + .buf = usb_current_xfer_info.buffer + }; + memcpy(param_buf, ¶m, sizeof(xfer_retry_param_t)); + + hcd_event_t event = { + .rhport = rhport, + .dev_addr = dev_addr, + .event_id = USBH_EVENT_FUNC_CALL, + .func_call = { + .func = xfer_retry, + .param = param_buf + } + }; + hcd_event_handler(&event, in_isr); } return; } else if (response_pid == USB_PID_DATA0 || response_pid == USB_PID_DATA1) { LOG_CH32_USBFSH("Data toggle mismatched and DATA0/1 (not STALL). RX_LEN=%d\r\n", USBOTG_H_FS->RX_LEN); usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, in_isr); return; } else { LOG_CH32_USBFSH("hcd_int_handler() L%d: unexpected response PID: 0x%02x\r\n", __LINE__, response_pid); usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, in_isr); return; } } @@ -495,6 +547,8 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const uint8_t xfer_type = ep_desc->bmAttributes.xfer; LOG_CH32_USBFSH("hcd_edpt_open(rhport=%d, dev_addr=0x%02x, %p) EndpointAdderss=0x%02x,maxPacketSize=%d,xfer_type=%d\r\n", rhport, dev_addr, ep_desc, ep_addr, max_packet_size, xfer_type); + while (usb_current_xfer_info.is_busy) { } + if (ep_num == 0x00) { TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x00, max_packet_size, xfer_type) != NULL, false); TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x80, max_packet_size, xfer_type) != NULL, false); @@ -529,6 +583,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b usb_current_xfer_info.bufferlen = buflen; usb_current_xfer_info.start_ms = board_millis(); usb_current_xfer_info.xferred_len = 0; + usb_current_xfer_info.nak_pending = false; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { LOG_CH32_USBFSH("hcd_edpt_xfer(): READ, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen); @@ -581,6 +636,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet usb_current_xfer_info.buffer = USBFS_TX_Buf; usb_current_xfer_info.bufferlen = setup_packet_datalen; usb_current_xfer_info.xferred_len = 0; + usb_current_xfer_info.nak_pending = false; hardware_start_xfer(USB_PID_SETUP, 0, 0); From 6f2b5fc4952e0fc730466a8756ce6427c33ce2b7 Mon Sep 17 00:00:00 2001 From: Mitsumine Suzu <60875431+verylowfreq@users.noreply.github.com> Date: Sun, 24 Aug 2025 23:52:52 +0900 Subject: [PATCH 4/5] Remove dynamic memory allocation --- src/portable/wch/hcd_ch32_usbfs.c | 46 ++++++++++++++----------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c index 449908658..ff34ae17a 100644 --- a/src/portable/wch/hcd_ch32_usbfs.c +++ b/src/portable/wch/hcd_ch32_usbfs.c @@ -84,6 +84,10 @@ typedef struct usb_edpt { // Data toggle (0 or not 0) for DATA0/1 uint8_t data_toggle; + + bool is_nak_pending; + uint16_t buflen; + uint8_t* buf; } usb_edpt_t; static usb_edpt_t usb_edpt_list[CFG_TUH_DEVICE_MAX * 6] = {}; @@ -130,6 +134,9 @@ static usb_edpt_t *add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t m slot->max_packet_size = max_packet_size; slot->xfer_type = xfer_type; slot->data_toggle = 0; + slot->is_nak_pending = false; + slot->buflen = 0; + slot->buf = NULL; slot->configured = true; @@ -354,28 +361,22 @@ void hcd_int_disable(uint8_t rhport) { interrupt_enabled = false; } -typedef struct { - uint8_t rhport; - uint8_t dev_addr; - uint8_t ep_addr; - uint16_t buflen; - uint8_t* buf; -} xfer_retry_param_t; static void xfer_retry(void* _params) { LOG_CH32_USBFSH("xfer_retry()\r\n"); - xfer_retry_param_t* params = (xfer_retry_param_t*)_params; + usb_edpt_t* edpt_info = (usb_edpt_t*)_params; if (usb_current_xfer_info.nak_pending) { usb_current_xfer_info.nak_pending = false; + edpt_info->is_nak_pending = false; - uint8_t dev_addr = params->dev_addr; - uint8_t ep_addr = params->ep_addr; - uint16_t buflen = params->buflen; - uint8_t* buf = params->buf; - free(params); + uint8_t dev_addr = edpt_info->dev_addr; + uint8_t ep_addr = edpt_info->ep_addr; + uint16_t buflen = edpt_info->buflen; + uint8_t* buf = edpt_info->buf; - usb_edpt_t* edpt_info = get_edpt_record(dev_addr, ep_addr); - if (edpt_info) { + // Check connectivity + usb_edpt_t* edpt_info_current = get_edpt_record(dev_addr, ep_addr); + if (edpt_info_current) { hcd_edpt_xfer(0, dev_addr, ep_addr, buf, buflen); } } @@ -498,15 +499,10 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { usb_current_xfer_info.is_busy = false; usb_current_xfer_info.nak_pending = true; - xfer_retry_param_t* param_buf = malloc(sizeof(xfer_retry_param_t)); - xfer_retry_param_t param = { - .rhport = 0, - .dev_addr = dev_addr, - .ep_addr = ep_addr, - .buflen = usb_current_xfer_info.bufferlen, - .buf = usb_current_xfer_info.buffer - }; - memcpy(param_buf, ¶m, sizeof(xfer_retry_param_t)); + + edpt_info->is_nak_pending = true; + edpt_info->buflen = usb_current_xfer_info.bufferlen; + edpt_info->buf = usb_current_xfer_info.buffer; hcd_event_t event = { .rhport = rhport, @@ -514,7 +510,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { .event_id = USBH_EVENT_FUNC_CALL, .func_call = { .func = xfer_retry, - .param = param_buf + .param = edpt_info } }; hcd_event_handler(&event, in_isr); From f5d04833bb5841930476cc666193f2f362aef228 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Sep 2025 13:30:20 +0700 Subject: [PATCH 5/5] use tusb_time_millis_api() instead of board_millis() make loopdelay() always inline --- src/portable/wch/hcd_ch32_usbfs.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c index ff34ae17a..200136906 100644 --- a/src/portable/wch/hcd_ch32_usbfs.c +++ b/src/portable/wch/hcd_ch32_usbfs.c @@ -57,20 +57,18 @@ TU_ATTR_ALIGNED(4) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN]; #define LOG_CH32_USBFSH(...) TU_LOG3(__VA_ARGS__) // Busywait for delay microseconds/nanoseconds -static void loopdelay(uint32_t count) -{ - volatile uint32_t c = count / 3; - if (c == 0) { return; } - // while (c-- != 0); - asm volatile( - "1: \n" // loop label - " addi %0, %0, -1 \n" // c-- - " bne %0, zero, 1b \n" // if (c != 0) goto loop - : "+r"(c) // c is input/output operand +TU_ATTR_ALWAYS_INLINE static inline void loopdelay(uint32_t count) { + volatile uint32_t c = count / 3; + if (c == 0) { return; } + // while (c-- != 0); + asm volatile( + "1: \n" // loop label + " addi %0, %0, -1 \n" // c-- + " bne %0, zero, 1b \n" // if (c != 0) goto loop + : "+r"(c) // c is input/output operand ); } - // Endpoint status typedef struct usb_edpt { // Is this a valid struct @@ -346,7 +344,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; - return board_millis(); + return tusb_time_millis_api(); } void hcd_int_enable(uint8_t rhport) { @@ -489,7 +487,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { return; } else if (response_pid == USB_PID_NAK) { LOG_CH32_USBFSH("NAK reposense\r\n"); - uint32_t elapsed_time = board_millis() - usb_current_xfer_info.start_ms; + uint32_t elapsed_time = tusb_time_millis_api() - usb_current_xfer_info.start_ms; (void)elapsed_time; if (edpt_info->xfer_type == TUSB_XFER_INTERRUPT) { usb_current_xfer_info.is_busy = false; @@ -577,7 +575,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b usb_current_xfer_info.ep_addr = ep_addr; usb_current_xfer_info.buffer = buffer; usb_current_xfer_info.bufferlen = buflen; - usb_current_xfer_info.start_ms = board_millis(); + usb_current_xfer_info.start_ms = tusb_time_millis_api(); usb_current_xfer_info.xferred_len = 0; usb_current_xfer_info.nak_pending = false; @@ -628,7 +626,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet uint8_t ep_addr = (setup_packet[0] & 0x80) ? 0x80 : 0x00; usb_current_xfer_info.dev_addr = dev_addr; usb_current_xfer_info.ep_addr = ep_addr; - usb_current_xfer_info.start_ms = board_millis(); + usb_current_xfer_info.start_ms = tusb_time_millis_api(); usb_current_xfer_info.buffer = USBFS_TX_Buf; usb_current_xfer_info.bufferlen = setup_packet_datalen; usb_current_xfer_info.xferred_len = 0;