move usbh ctrl_xfer into usbh_data

This commit is contained in:
hathach
2025-04-23 16:50:58 +07:00
parent a2da575793
commit 9a1f690ec4

View File

@@ -263,7 +263,7 @@ static osal_queue_t _usbh_q;
// Control transfers: since most controllers do not support multiple control transfers // Control transfers: since most controllers do not support multiple control transfers
// on multiple devices concurrently and control transfers are not used much except for // on multiple devices concurrently and control transfers are not used much except for
// enumeration, we will only execute control transfers one at a time. // enumeration, we will only execute control transfers one at a time.
static struct { typedef struct {
uint8_t* buffer; uint8_t* buffer;
tuh_xfer_cb_t complete_cb; tuh_xfer_cb_t complete_cb;
uintptr_t user_data; uintptr_t user_data;
@@ -272,26 +272,25 @@ static struct {
uint8_t daddr; uint8_t daddr;
volatile uint16_t actual_len; volatile uint16_t actual_len;
uint8_t failed_count; uint8_t failed_count;
} _ctrl_xfer; } usbh_ctrl_xfer_info_t;
typedef struct { typedef struct {
TUH_EPBUF_TYPE_DEF(tusb_control_request_t, request); uint8_t controller_id; // controller ID
TUH_EPBUF_DEF(ctrl, CFG_TUH_ENUMERATION_BUFSIZE); uint8_t enumerating_daddr; // device address of the device being enumerated
} usbh_epbuf_t; tuh_bus_info_t dev0_bus; // bus info for dev0 in enumeration
usbh_ctrl_xfer_info_t ctrl_xfer_info; // control transfer
CFG_TUH_MEM_SECTION static usbh_epbuf_t _usbh_epbuf;
typedef struct {
uint8_t controller_id; // controller ID
uint8_t enumerating_daddr; // device address of the device being enumerated
tuh_bus_info_t dev0_bus; // bus info for dev0 in enumeration
} usbh_data_t; } usbh_data_t;
static usbh_data_t _usbh_data = { static usbh_data_t _usbh_data = {
.controller_id = TUSB_INDEX_INVALID_8, .controller_id = TUSB_INDEX_INVALID_8,
}; };
typedef struct {
TUH_EPBUF_TYPE_DEF(tusb_control_request_t, request);
TUH_EPBUF_DEF(ctrl, CFG_TUH_ENUMERATION_BUFSIZE);
} usbh_epbuf_t;
CFG_TUH_MEM_SECTION static usbh_epbuf_t _usbh_epbuf;
//------------- Helper Function -------------// //------------- Helper Function -------------//
TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) { TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr) {
TU_VERIFY(dev_addr > 0 && dev_addr <= TOTAL_DEVICES, NULL); TU_VERIFY(dev_addr > 0 && dev_addr <= TOTAL_DEVICES, NULL);
@@ -299,7 +298,7 @@ TU_ATTR_ALWAYS_INLINE static inline usbh_device_t* get_device(uint8_t dev_addr)
} }
static bool enum_new_device(hcd_event_t* event); static bool enum_new_device(hcd_event_t* event);
static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port); static void process_removed_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port);
static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size); static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size);
static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes); static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
@@ -388,9 +387,9 @@ bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
// Init host stack if not already // Init host stack if not already
if (!tuh_inited()) { if (!tuh_inited()) {
TU_LOG_INT_USBH(sizeof(usbh_data_t));
TU_LOG_INT_USBH(sizeof(usbh_device_t)); TU_LOG_INT_USBH(sizeof(usbh_device_t));
TU_LOG_INT_USBH(sizeof(hcd_event_t)); TU_LOG_INT_USBH(sizeof(hcd_event_t));
TU_LOG_INT_USBH(sizeof(_ctrl_xfer));
TU_LOG_INT_USBH(sizeof(tuh_xfer_t)); TU_LOG_INT_USBH(sizeof(tuh_xfer_t));
TU_LOG_INT_USBH(sizeof(tu_fifo_t)); TU_LOG_INT_USBH(sizeof(tu_fifo_t));
TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t)); TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t));
@@ -412,7 +411,6 @@ bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
// Device // Device
tu_memclr(_usbh_devices, sizeof(_usbh_devices)); tu_memclr(_usbh_devices, sizeof(_usbh_devices));
tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer));
tu_memclr(&_usbh_data, sizeof(_usbh_data)); tu_memclr(&_usbh_data, sizeof(_usbh_data));
_usbh_data.controller_id = TUSB_INDEX_INVALID_8; _usbh_data.controller_id = TUSB_INDEX_INVALID_8;
@@ -451,7 +449,7 @@ bool tuh_deinit(uint8_t rhport) {
_usbh_data.controller_id = TUSB_INDEX_INVALID_8; _usbh_data.controller_id = TUSB_INDEX_INVALID_8;
// "unplug" all devices on this rhport (hub_addr = 0, hub_port = 0) // "unplug" all devices on this rhport (hub_addr = 0, hub_port = 0)
process_removing_device(rhport, 0, 0); process_removed_device(rhport, 0, 0);
// deinit host stack if no controller is active // deinit host stack if no controller is active
if (!tuh_inited()) { if (!tuh_inited()) {
@@ -545,7 +543,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
case HCD_EVENT_DEVICE_REMOVE: case HCD_EVENT_DEVICE_REMOVE:
TU_LOG_USBH("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port); TU_LOG_USBH("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port);
process_removing_device(event.rhport, event.connection.hub_addr, event.connection.hub_port); process_removed_device(event.rhport, event.connection.hub_addr, event.connection.hub_port);
#if CFG_TUH_HUB #if CFG_TUH_HUB
// TODO remove // TODO remove
@@ -638,9 +636,9 @@ static void _control_blocking_complete_cb(tuh_xfer_t* xfer) {
} }
TU_ATTR_ALWAYS_INLINE static inline void _control_set_xfer_stage(uint8_t stage) { TU_ATTR_ALWAYS_INLINE static inline void _control_set_xfer_stage(uint8_t stage) {
if (_ctrl_xfer.stage != stage) { if (_usbh_data.ctrl_xfer_info.stage != stage) {
(void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
_ctrl_xfer.stage = stage; _usbh_data.ctrl_xfer_info.stage = stage;
(void) osal_mutex_unlock(_usbh_mutex); (void) osal_mutex_unlock(_usbh_mutex);
} }
} }
@@ -660,23 +658,22 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) {
const uint8_t daddr = xfer->daddr; const uint8_t daddr = xfer->daddr;
TU_VERIFY(tuh_connected(daddr)); TU_VERIFY(tuh_connected(daddr));
// pre-check to help reducing mutex lock usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info;
TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE);
TU_VERIFY(ctrl_info->stage == CONTROL_STAGE_IDLE); // pre-check to help reducing mutex lock
(void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
bool const is_idle = (ctrl_info->stage == CONTROL_STAGE_IDLE);
bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE);
if (is_idle) { if (is_idle) {
_ctrl_xfer.stage = CONTROL_STAGE_SETUP; ctrl_info->stage = CONTROL_STAGE_SETUP;
_ctrl_xfer.daddr = daddr; ctrl_info->daddr = daddr;
_ctrl_xfer.actual_len = 0; ctrl_info->actual_len = 0;
_ctrl_xfer.failed_count = 0; ctrl_info->failed_count = 0;
_ctrl_xfer.buffer = xfer->buffer; ctrl_info->buffer = xfer->buffer;
_ctrl_xfer.complete_cb = xfer->complete_cb; ctrl_info->complete_cb = xfer->complete_cb;
_ctrl_xfer.user_data = xfer->user_data; ctrl_info->user_data = xfer->user_data;
_usbh_epbuf.request = (*xfer->setup); _usbh_epbuf.request = (*xfer->setup);
} }
(void) osal_mutex_unlock(_usbh_mutex); (void) osal_mutex_unlock(_usbh_mutex);
TU_VERIFY(is_idle); TU_VERIFY(is_idle);
@@ -693,8 +690,8 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) {
volatile xfer_result_t result = XFER_RESULT_INVALID; volatile xfer_result_t result = XFER_RESULT_INVALID;
// use user_data to point to xfer_result_t // use user_data to point to xfer_result_t
_ctrl_xfer.user_data = (uintptr_t) &result; ctrl_info->user_data = (uintptr_t) &result;
_ctrl_xfer.complete_cb = _control_blocking_complete_cb; ctrl_info->complete_cb = _control_blocking_complete_cb;
TU_ASSERT(usbh_setup_send(daddr, (uint8_t const *) &_usbh_epbuf.request)); TU_ASSERT(usbh_setup_send(daddr, (uint8_t const *) &_usbh_epbuf.request));
@@ -712,7 +709,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) {
*((xfer_result_t*) xfer->user_data) = result; *((xfer_result_t*) xfer->user_data) = result;
} }
xfer->result = result; xfer->result = result;
xfer->actual_len = _ctrl_xfer.actual_len; xfer->actual_len = ctrl_info->actual_len;
} }
return true; return true;
@@ -720,6 +717,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) {
static void _control_xfer_complete(uint8_t daddr, xfer_result_t result) { static void _control_xfer_complete(uint8_t daddr, xfer_result_t result) {
TU_LOG_USBH("\r\n"); TU_LOG_USBH("\r\n");
usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info;
// duplicate xfer since user can execute control transfer within callback // duplicate xfer since user can execute control transfer within callback
tusb_control_request_t const request = _usbh_epbuf.request; tusb_control_request_t const request = _usbh_epbuf.request;
@@ -728,10 +726,10 @@ static void _control_xfer_complete(uint8_t daddr, xfer_result_t result) {
.ep_addr = 0, .ep_addr = 0,
.result = result, .result = result,
.setup = &request, .setup = &request,
.actual_len = (uint32_t) _ctrl_xfer.actual_len, .actual_len = (uint32_t) ctrl_info->actual_len,
.buffer = _ctrl_xfer.buffer, .buffer = ctrl_info->buffer,
.complete_cb = _ctrl_xfer.complete_cb, .complete_cb = ctrl_info->complete_cb,
.user_data = _ctrl_xfer.user_data .user_data = ctrl_info->user_data
}; };
_control_set_xfer_stage(CONTROL_STAGE_IDLE); _control_set_xfer_stage(CONTROL_STAGE_IDLE);
@@ -746,6 +744,7 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t
const uint8_t rhport = usbh_get_rhport(daddr); const uint8_t rhport = usbh_get_rhport(daddr);
tusb_control_request_t const * request = &_usbh_epbuf.request; tusb_control_request_t const * request = &_usbh_epbuf.request;
usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info;
switch (result) { switch (result) {
case XFER_RESULT_STALLED: case XFER_RESULT_STALLED:
@@ -755,12 +754,12 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t
break; break;
case XFER_RESULT_FAILED: case XFER_RESULT_FAILED:
if (tuh_connected(daddr) && _ctrl_xfer.failed_count < USBH_CONTROL_RETRY_MAX) { if (tuh_connected(daddr) && ctrl_info->failed_count < USBH_CONTROL_RETRY_MAX) {
TU_LOG_USBH("[%u:%u] Control FAILED %u/%u, retrying\r\n", rhport, daddr, _ctrl_xfer.failed_count+1, USBH_CONTROL_RETRY_MAX); TU_LOG_USBH("[%u:%u] Control FAILED %u/%u, retrying\r\n", rhport, daddr, ctrl_info->failed_count+1, USBH_CONTROL_RETRY_MAX);
(void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER); (void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
_ctrl_xfer.stage = CONTROL_STAGE_SETUP; ctrl_info->stage = CONTROL_STAGE_SETUP;
_ctrl_xfer.failed_count++; ctrl_info->failed_count++;
_ctrl_xfer.actual_len = 0; // reset actual_len ctrl_info->actual_len = 0; // reset actual_len
(void) osal_mutex_unlock(_usbh_mutex); (void) osal_mutex_unlock(_usbh_mutex);
TU_ASSERT(usbh_setup_send(daddr, (uint8_t const *) request)); TU_ASSERT(usbh_setup_send(daddr, (uint8_t const *) request));
@@ -772,28 +771,29 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t
break; break;
case XFER_RESULT_SUCCESS: case XFER_RESULT_SUCCESS:
switch(_ctrl_xfer.stage) { switch(ctrl_info->stage) {
case CONTROL_STAGE_SETUP: case CONTROL_STAGE_SETUP:
if (request->wLength) { if (request->wLength) {
// DATA stage: initial data toggle is always 1 // DATA stage: initial data toggle is always 1
_control_set_xfer_stage(CONTROL_STAGE_DATA); _control_set_xfer_stage(CONTROL_STAGE_DATA);
TU_ASSERT(hcd_edpt_xfer(rhport, daddr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength)); const uint8_t ep_data = tu_edpt_addr(0, request->bmRequestType_bit.direction);
TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_data, ctrl_info->buffer, request->wLength));
return true; return true;
} }
TU_ATTR_FALLTHROUGH; TU_ATTR_FALLTHROUGH;
case CONTROL_STAGE_DATA: case CONTROL_STAGE_DATA:
if (request->wLength) { if (request->wLength) {
TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr); TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr);
TU_LOG_MEM_USBH(_ctrl_xfer.buffer, xferred_bytes, 2); TU_LOG_MEM_USBH(ctrl_info->buffer, xferred_bytes, 2);
} }
ctrl_info->actual_len = (uint16_t) xferred_bytes;
_ctrl_xfer.actual_len = (uint16_t) xferred_bytes; // ACK stage: toggle is always 1
_control_set_xfer_stage(CONTROL_STAGE_ACK);
// ACK stage: toggle is always 1 const uint8_t ep_status = tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction);
_control_set_xfer_stage(CONTROL_STAGE_ACK); TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_status, NULL, 0));
TU_ASSERT( hcd_edpt_xfer(rhport, daddr, tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction), NULL, 0) ); break;
break;
case CONTROL_STAGE_ACK: { case CONTROL_STAGE_ACK: {
// Abort all pending transfers if SET_CONFIGURATION request // Abort all pending transfers if SET_CONFIGURATION request
@@ -842,16 +842,16 @@ bool tuh_edpt_xfer(tuh_xfer_t* xfer) {
bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) { bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) {
TU_LOG_USBH("[%u] Aborted transfer on EP %02X\r\n", daddr, ep_addr); TU_LOG_USBH("[%u] Aborted transfer on EP %02X\r\n", daddr, ep_addr);
const uint8_t epnum = tu_edpt_number(ep_addr); const uint8_t epnum = tu_edpt_number(ep_addr);
const uint8_t dir = tu_edpt_dir(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr);
if (epnum == 0) { if (epnum == 0) {
// Also include dev0_bus for aborting enumerating // Also include dev0 for aborting enumerating
const uint8_t rhport = usbh_get_rhport(daddr); const uint8_t rhport = usbh_get_rhport(daddr);
// control transfer: only 1 control at a time, check if we are aborting the current one // control transfer: only 1 control at a time, check if we are aborting the current one
TU_VERIFY(daddr == _ctrl_xfer.daddr && _ctrl_xfer.stage != CONTROL_STAGE_IDLE); const usbh_ctrl_xfer_info_t* ctrl_info = &_usbh_data.ctrl_xfer_info;
TU_VERIFY(daddr == ctrl_info->daddr && ctrl_info->stage != CONTROL_STAGE_IDLE);
hcd_edpt_abort_xfer(rhport, daddr, ep_addr); hcd_edpt_abort_xfer(rhport, daddr, ep_addr);
_control_set_xfer_stage(CONTROL_STAGE_IDLE); // reset control transfer state to idle _control_set_xfer_stage(CONTROL_STAGE_IDLE); // reset control transfer state to idle
} else { } else {
@@ -859,9 +859,8 @@ bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) {
TU_VERIFY(dev); TU_VERIFY(dev);
TU_VERIFY(dev->ep_status[epnum][dir].busy); // non-control skip if not busy TU_VERIFY(dev->ep_status[epnum][dir].busy); // non-control skip if not busy
// abort then mark as ready and release endpoint
hcd_edpt_abort_xfer(dev->bus_info.rhport, daddr, ep_addr); hcd_edpt_abort_xfer(dev->bus_info.rhport, daddr, ep_addr);
// mark as ready and release endpoint if transfer is aborted
dev->ep_status[epnum][dir].busy = false; dev->ep_status[epnum][dir].busy = false;
tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex); tu_edpt_release(&dev->ep_status[epnum][dir], _usbh_mutex);
} }
@@ -1252,16 +1251,18 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_hub_addr(uint8_t daddr) {
} }
// a device unplugged from rhport:hub_addr:hub_port // a device unplugged from rhport:hub_addr:hub_port
static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { static void process_removed_device(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) {
// dev0_bus is unplugged // if dev0 is unplugged while enumerating (not yet assigned an address)
if ((_usbh_data.enumerating_daddr == 0) && (rhport == _usbh_data.dev0_bus.rhport) && if (_usbh_data.enumerating_daddr == 0) {
(hub_addr == _usbh_data.dev0_bus.hub_addr) && (hub_port == _usbh_data.dev0_bus.hub_port)) { const tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus;
hcd_device_close(_usbh_data.dev0_bus.rhport, 0); if ((rhport == dev0_bus->rhport) && (hub_addr == dev0_bus->hub_addr) && (hub_port == dev0_bus->hub_port)) {
if (_ctrl_xfer.daddr == 0) { hcd_device_close(dev0_bus->rhport, 0);
_control_set_xfer_stage(CONTROL_STAGE_IDLE); if (_usbh_data.ctrl_xfer_info.daddr == 0) {
_control_set_xfer_stage(CONTROL_STAGE_IDLE);
}
_usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8;
return;
} }
_usbh_data.enumerating_daddr = TUSB_INDEX_INVALID_8;
return;
} }
//------------- find the all devices (star-network) under port that is unplugged -------------// //------------- find the all devices (star-network) under port that is unplugged -------------//
@@ -1298,8 +1299,8 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu
hcd_device_close(rhport, daddr); hcd_device_close(rhport, daddr);
clear_device(dev); clear_device(dev);
// abort on-going control xfer on this device if any // abort ongoing control xfer on this device if any
if (daddr == _ctrl_xfer.daddr) { if (daddr == _usbh_data.ctrl_xfer_info.daddr) {
_control_set_xfer_stage(CONTROL_STAGE_IDLE); _control_set_xfer_stage(CONTROL_STAGE_IDLE);
} }
@@ -1651,45 +1652,45 @@ static void process_enumeration(tuh_xfer_t* xfer) {
} }
static bool enum_new_device(hcd_event_t* event) { static bool enum_new_device(hcd_event_t* event) {
_usbh_data.dev0_bus.rhport = event->rhport; tuh_bus_info_t* dev0_bus = &_usbh_data.dev0_bus;
_usbh_data.dev0_bus.hub_addr = event->connection.hub_addr; dev0_bus->rhport = event->rhport;
_usbh_data.dev0_bus.hub_port = event->connection.hub_port; dev0_bus->hub_addr = event->connection.hub_addr;
dev0_bus->hub_port = event->connection.hub_port;
if (_usbh_data.dev0_bus.hub_addr == 0) { if (dev0_bus->hub_addr == 0) {
// connected directly to roothub // connected directly to roothub
// wait until device connection is stable TODO non blocking // wait until device connection is stable TODO non blocking
tusb_time_delay_ms_api(ENUM_DEBOUNCING_DELAY_MS); tusb_time_delay_ms_api(ENUM_DEBOUNCING_DELAY_MS);
// device unplugged while delaying if (!hcd_port_connect_status(dev0_bus->rhport)) {
if (!hcd_port_connect_status(_usbh_data.dev0_bus.rhport)) { TU_LOG_USBH("Device unplugged while debouncing\r\n");
enum_full_complete(); enum_full_complete();
return true; return true;
} }
hcd_port_reset(_usbh_data.dev0_bus.rhport); // reset device hcd_port_reset(dev0_bus->rhport); // reset device
// Since we are in middle of rhport reset, frame number is not available yet. // Since we are in middle of rhport reset, frame number is not available yet.
// need to depend on tusb_time_millis_api() // need to depend on tusb_time_millis_api() TODO non blocking
tusb_time_delay_ms_api(ENUM_RESET_DELAY_MS); tusb_time_delay_ms_api(ENUM_RESET_DELAY_MS);
hcd_port_reset_end(_usbh_data.dev0_bus.rhport); hcd_port_reset_end(dev0_bus->rhport);
// device unplugged while delaying // device unplugged while delaying
if (!hcd_port_connect_status(_usbh_data.dev0_bus.rhport)) { if (!hcd_port_connect_status(dev0_bus->rhport)) {
enum_full_complete(); enum_full_complete();
return true; return true;
} }
_usbh_data.dev0_bus.speed = hcd_port_speed_get(_usbh_data.dev0_bus.rhport); dev0_bus->speed = hcd_port_speed_get(dev0_bus->rhport);
TU_LOG_USBH("%s Speed\r\n", tu_str_speed[_usbh_data.dev0.speed]); TU_LOG_USBH("%s Speed\r\n", tu_str_speed[dev0_bus->speed]);
// fake transfer to kick-off the enumeration process // fake transfer to kick-off the enumeration process
tuh_xfer_t xfer; tuh_xfer_t xfer;
xfer.daddr = 0; xfer.daddr = 0;
xfer.result = XFER_RESULT_SUCCESS; xfer.result = XFER_RESULT_SUCCESS;
xfer.user_data = ENUM_ADDR0_DEVICE_DESC; xfer.user_data = ENUM_ADDR0_DEVICE_DESC;
process_enumeration(&xfer); process_enumeration(&xfer);
} }
#if CFG_TUH_HUB #if CFG_TUH_HUB
@@ -1699,7 +1700,7 @@ static bool enum_new_device(hcd_event_t* event) {
tusb_time_delay_ms_api(ENUM_DEBOUNCING_DELAY_MS); tusb_time_delay_ms_api(ENUM_DEBOUNCING_DELAY_MS);
// ENUM_HUB_GET_STATUS // ENUM_HUB_GET_STATUS
TU_ASSERT(hub_port_get_status(_usbh_data.dev0_bus.hub_addr, _usbh_data.dev0_bus.hub_port, _usbh_epbuf.ctrl, TU_ASSERT(hub_port_get_status(dev0_bus->hub_addr, dev0_bus->hub_port, _usbh_epbuf.ctrl,
process_enumeration, ENUM_HUB_CLEAR_RESET_1)); process_enumeration, ENUM_HUB_CLEAR_RESET_1));
} }
#endif // hub #endif // hub