diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 8ca3dfbc..9838df81 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -124,22 +124,24 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_co { cdch_data_t const * p_cdc = get_itf(dev_addr); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, + .wValue = (rts ? 2 : 0) | (dtr ? 1 : 0), + .wIndex = p_cdc->itf_num, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE, - .wValue = (rts ? 2 : 0) | (dtr ? 1 : 0), - .wIndex = p_cdc->itf_num, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = 0 diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 6bcd2f5d..8c1a5ebc 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -105,11 +105,11 @@ uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) static bool set_protocol_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { - uint8_t const itf_num = (uint8_t) xfer->request.wIndex; + uint8_t const itf_num = (uint8_t) xfer->setup->wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - if (XFER_RESULT_SUCCESS == result) hid_itf->protocol_mode = (uint8_t) xfer->request.wValue; + if (XFER_RESULT_SUCCESS == result) hid_itf->protocol_mode = (uint8_t) xfer->setup->wValue; if (tuh_hid_set_protocol_complete_cb) { @@ -124,22 +124,24 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc { TU_LOG2("HID Set Protocol = %d\r\n", protocol); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, + .wValue = protocol, + .wIndex = itf_num, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, - .wValue = protocol, - .wIndex = itf_num, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = user_arg @@ -163,13 +165,13 @@ static bool set_report_complete(uint8_t dev_addr, tuh_control_xfer_t const * xfe if (tuh_hid_set_report_complete_cb) { - uint8_t const itf_num = (uint8_t) xfer->request.wIndex; + uint8_t const itf_num = (uint8_t) xfer->setup->wIndex; uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); - uint8_t const report_type = tu_u16_high(xfer->request.wValue); - uint8_t const report_id = tu_u16_low(xfer->request.wValue); + uint8_t const report_type = tu_u16_high(xfer->setup->wValue); + uint8_t const report_id = tu_u16_low(xfer->setup->wValue); - tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, (result == XFER_RESULT_SUCCESS) ? xfer->request.wLength : 0); + tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, (result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); } return true; @@ -180,22 +182,24 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u hidh_interface_t* hid_itf = get_instance(dev_addr, instance); TU_LOG2("HID Set Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_REPORT, + .wValue = tu_u16(report_type, report_id), + .wIndex = hid_itf->itf_num, + .wLength = len + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_REPORT, - .wValue = tu_u16(report_type, report_id), - .wIndex = hid_itf->itf_num, - .wLength = len - }, - + .ep_addr = 0, + .setup = &request, .buffer = report, .complete_cb = set_report_complete, .user_arg = 0 @@ -209,22 +213,24 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate { // SET IDLE request, device can stall if not support this request TU_LOG2("HID Set Idle \r\n"); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_IDLE, + .wValue = idle_rate, + .wIndex = itf_num, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HID_REQ_CONTROL_SET_IDLE, - .wValue = idle_rate, - .wIndex = itf_num, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = user_arg @@ -387,24 +393,27 @@ static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) { + tusb_control_request_t request; + request.wIndex = tu_htole16((uint16_t) itf_num); + tuh_control_xfer_t xfer; - xfer.request.wIndex = tu_htole16((uint16_t) itf_num); + xfer.setup = &request; xfer.user_arg = CONFG_SET_IDLE; - // start the set config process + // fake request to start the set config process return process_set_config(dev_addr, &xfer, XFER_RESULT_SUCCESS); } static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer, xfer_result_t result) { // Stall is a valid response for SET_IDLE, therefore we could ignore its result - if ( xfer->request.bRequest != HID_REQ_CONTROL_SET_IDLE ) + if ( xfer->setup->bRequest != HID_REQ_CONTROL_SET_IDLE ) { TU_ASSERT(result == XFER_RESULT_SUCCESS); } uintptr_t const state = xfer->user_arg; - uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->request.wIndex); + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); hidh_interface_t* hid_itf = get_instance(dev_addr, instance); @@ -441,7 +450,7 @@ static bool process_set_config(uint8_t dev_addr, tuh_control_xfer_t const * xfer case CONFIG_COMPLETE: { uint8_t const* desc_report = usbh_get_enum_buf(); - uint16_t const desc_len = xfer->request.wLength; + uint16_t const desc_len = xfer->setup->wLength; config_driver_mount_complete(dev_addr, instance, desc_report, desc_len); } diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index b3af6594..d8910db0 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -405,22 +405,24 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) //------------- Get Max Lun -------------// TU_LOG2("MSC Get Max Lun\r\n"); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = MSC_REQ_GET_MAX_LUN, + .wValue = 0, + .wIndex = itf_num, + .wLength = 1 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = MSC_REQ_GET_MAX_LUN, - .wValue = 0, - .wIndex = itf_num, - .wLength = 1 - }, - + .ep_addr = 0, + .setup = &request, .buffer = &p_msc->max_lun, .complete_cb = config_get_maxlun_complete, .user_arg = 0 diff --git a/src/host/hub.c b/src/host/hub.c index c1909cb5..6ce9e4cc 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -80,22 +80,24 @@ static char const* const _hub_feature_str[] = bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HUB_REQUEST_CLEAR_FEATURE, + .wValue = feature, + .wIndex = hub_port, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_OTHER, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HUB_REQUEST_CLEAR_FEATURE, - .wValue = feature, - .wIndex = hub_port, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = user_arg @@ -109,22 +111,24 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HUB_REQUEST_SET_FEATURE, + .wValue = feature, + .wIndex = hub_port, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_OTHER, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_OUT - }, - .bRequest = HUB_REQUEST_SET_FEATURE, - .wValue = feature, - .wIndex = hub_port, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = user_arg @@ -138,22 +142,24 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_OTHER, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HUB_REQUEST_GET_STATUS, + .wValue = 0, + .wIndex = hub_port, + .wLength = 4 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_OTHER, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = HUB_REQUEST_GET_STATUS, - .wValue = 0, - .wIndex = hub_port, - .wLength = 4 - }, - + .ep_addr = 0, + .setup = &request, .buffer = resp, .complete_cb = complete_cb, .user_arg = user_arg @@ -228,22 +234,24 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) TU_ASSERT(itf_num == p_hub->itf_num); // Get Hub Descriptor + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_IN + }, + .bRequest = HUB_REQUEST_GET_DESCRIPTOR, + .wValue = 0, + .wIndex = 0, + .wLength = sizeof(descriptor_hub_desc_t) + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_CLASS, - .direction = TUSB_DIR_IN - }, - .bRequest = HUB_REQUEST_GET_DESCRIPTOR, - .wValue = 0, - .wIndex = 0, - .wLength = sizeof(descriptor_hub_desc_t) - }, - + .ep_addr = 0, + .setup = &request, .buffer = _hub_buffer, .complete_cb = config_set_port_power, .user_arg = 0 @@ -277,7 +285,7 @@ static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t con TU_ASSERT(XFER_RESULT_SUCCESS == result); hub_interface_t* p_hub = get_itf(dev_addr); - if (xfer->request.wIndex == p_hub->port_count) + if (xfer->setup->wIndex == p_hub->port_count) { // All ports are power -> queue notification status endpoint and // complete the SET CONFIGURATION @@ -287,7 +295,7 @@ static bool config_port_power_complete (uint8_t dev_addr, tuh_control_xfer_t con }else { // power next port - uint8_t const hub_port = (uint8_t) (xfer->request.wIndex + 1); + uint8_t const hub_port = (uint8_t) (xfer->setup->wIndex + 1); return hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } @@ -333,7 +341,7 @@ static bool connection_get_status_complete (uint8_t dev_addr, tuh_control_xfer_t TU_ASSERT(result == XFER_RESULT_SUCCESS); hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) xfer->request.wIndex; + uint8_t const port_num = (uint8_t) xfer->setup->wIndex; // Connection change if (p_hub->port_status.change.connection) @@ -361,7 +369,7 @@ static bool connection_clear_conn_change_complete (uint8_t dev_addr, tuh_control TU_ASSERT(result == XFER_RESULT_SUCCESS); hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) xfer->request.wIndex; + uint8_t const port_num = (uint8_t) xfer->setup->wIndex; if ( p_hub->port_status.status.connection ) { @@ -392,7 +400,7 @@ static bool connection_port_reset_complete (uint8_t dev_addr, tuh_control_xfer_t TU_ASSERT(result == XFER_RESULT_SUCCESS); // hub_interface_t* p_hub = get_itf(dev_addr); - uint8_t const port_num = (uint8_t) xfer->request.wIndex; + uint8_t const port_num = (uint8_t) xfer->setup->wIndex; // submit attach event hcd_event_t event = diff --git a/src/host/usbh.c b/src/host/usbh.c index 83bca220..d2d819ec 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -109,6 +109,10 @@ typedef struct { tu_edpt_state_t ep_status[CFG_TUH_ENDPOINT_MAX][2]; +#if CFG_TUH_BARE + +#endif + } usbh_device_t; //--------------------------------------------------------------------+ @@ -241,7 +245,11 @@ static uint8_t _usbh_ctrl_buf[CFG_TUH_ENUMERATION_BUFSIZE]; // We will only execute control transfer one at a time. struct { - tuh_control_xfer_t xfer; + tusb_control_request_t request TU_ATTR_ALIGNED(4); + uint8_t* buffer; + tuh_control_xfer_cb_t complete_cb; + uintptr_t user_arg; + uint8_t daddr; // device address that is transferring volatile uint8_t stage; }_ctrl_xfer; @@ -304,22 +312,24 @@ void osal_task_delay(uint32_t msec) static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t language_id, void* buffer, uint16_t len, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16( TU_U16(type, index) ), + .wIndex = tu_htole16(language_id), + .wLength = tu_htole16(len) + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16( TU_U16(type, index) ), - .wIndex = tu_htole16(language_id), - .wLength = tu_htole16(len) - }, - + .ep_addr = 0, + .setup = &request, .buffer = buffer, .complete_cb = complete_cb, .user_arg = user_arg @@ -387,22 +397,24 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg) { TU_LOG2("HID Get Report Descriptor\r\n"); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_IN + }, + .bRequest = TUSB_REQ_GET_DESCRIPTOR, + .wValue = tu_htole16(TU_U16(desc_type, index)), + .wIndex = tu_htole16((uint16_t) itf_num), + .wLength = len + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_INTERFACE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_IN - }, - .bRequest = TUSB_REQ_GET_DESCRIPTOR, - .wValue = tu_htole16(TU_U16(desc_type, index)), - .wIndex = tu_htole16((uint16_t) itf_num), - .wLength = len - }, - + .ep_addr = 0, + .setup = &request, .buffer = buffer, .complete_cb = complete_cb, .user_arg = user_arg @@ -416,22 +428,24 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, { TU_LOG2("Set Configuration = %d\r\n", config_num); + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_CONFIGURATION, + .wValue = tu_htole16(config_num), + .wIndex = 0, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_CONFIGURATION, - .wValue = tu_htole16(config_num), - .wIndex = 0, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = complete_cb, .user_arg = user_arg @@ -895,16 +909,19 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) const uint8_t rhport = usbh_get_rhport(daddr); - TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->request.bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->request.bRequest] : "Unknown Request"); - TU_LOG2_VAR(&xfer->request); + TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request"); + TU_LOG2_VAR(&xfer->setup); TU_LOG2("\r\n"); - _ctrl_xfer.daddr = daddr; - _ctrl_xfer.xfer = (*xfer); + _ctrl_xfer.daddr = daddr; + _ctrl_xfer.request = (*xfer->setup); + _ctrl_xfer.buffer = xfer->buffer; + _ctrl_xfer.complete_cb = xfer->complete_cb; + _ctrl_xfer.user_arg = xfer->user_arg; if (xfer->complete_cb) { - TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.xfer.request) ); + TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); }else { // user_arg must point to xfer_result_t to hold result @@ -914,10 +931,10 @@ bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer) // change callback to internal blocking, and result as user argument volatile xfer_result_t* result = (volatile xfer_result_t*) xfer->user_arg; - _ctrl_xfer.xfer.complete_cb = _control_blocking_complete_cb; + _ctrl_xfer.complete_cb = _control_blocking_complete_cb; *result = XFER_RESULT_INVALID; - TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.xfer.request) ); + TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); while ((*result) == XFER_RESULT_INVALID) { @@ -961,7 +978,16 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) TU_LOG2("\r\n"); // duplicate xfer since user can execute control transfer within callback - tuh_control_xfer_t const xfer_temp = _ctrl_xfer.xfer; + tusb_control_request_t const request = _ctrl_xfer.request; + tuh_control_xfer_t const xfer_temp = + { + .ep_addr = 0, + .setup = &request, + .actual_len = 0, + .buffer = _ctrl_xfer.buffer, + .complete_cb = _ctrl_xfer.complete_cb, + .user_arg = _ctrl_xfer.user_arg + }; usbh_lock(); _ctrl_xfer.stage = CONTROL_STAGE_IDLE; @@ -979,7 +1005,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result (void) xferred_bytes; const uint8_t rhport = usbh_get_rhport(dev_addr); - tusb_control_request_t const * request = &_ctrl_xfer.xfer.request; + tusb_control_request_t const * request = &_ctrl_xfer.request; if (XFER_RESULT_SUCCESS != result) { @@ -996,7 +1022,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result { // DATA stage: initial data toggle is always 1 set_control_xfer_stage(CONTROL_STAGE_DATA); - return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.xfer.buffer, request->wLength); + return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength); } __attribute__((fallthrough)); @@ -1004,7 +1030,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result if (request->wLength) { TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr); - TU_LOG2_MEM(_ctrl_xfer.xfer.buffer, request->wLength, 2); + TU_LOG2_MEM(_ctrl_xfer.buffer, request->wLength, 2); } // ACK stage: toggle is always 1 @@ -1190,7 +1216,7 @@ static bool process_enumeration(uint8_t dev_addr, tuh_control_xfer_t const * xfe case ENUM_GET_DEVICE_DESC: { - uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->request.wValue); + uint8_t const new_addr = (uint8_t) tu_le16toh(xfer->setup->wValue); usbh_device_t* new_dev = get_device(new_addr); TU_ASSERT(new_dev); @@ -1320,6 +1346,12 @@ static bool enum_new_device(hcd_event_t* event) return true; } +TU_ATTR_ALWAYS_INLINE +static inline bool is_hub_addr(uint8_t daddr) +{ + return daddr > CFG_TUH_DEVICE_MAX; +} + static uint8_t get_new_address(bool is_hub) { uint8_t start; @@ -1360,22 +1392,24 @@ static bool enum_request_set_addr(void) new_dev->connected = 1; new_dev->ep0_size = desc_device->bMaxPacketSize0; + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_DEVICE, + .type = TUSB_REQ_TYPE_STANDARD, + .direction = TUSB_DIR_OUT + }, + .bRequest = TUSB_REQ_SET_ADDRESS, + .wValue = tu_htole16(new_addr), + .wIndex = 0, + .wLength = 0 + }; + tuh_control_xfer_t const xfer = { - .request = - { - .bmRequestType_bit = - { - .recipient = TUSB_REQ_RCPT_DEVICE, - .type = TUSB_REQ_TYPE_STANDARD, - .direction = TUSB_DIR_OUT - }, - .bRequest = TUSB_REQ_SET_ADDRESS, - .wValue = tu_htole16(new_addr), - .wIndex = 0, - .wLength = 0 - }, - + .ep_addr = 0, + .setup = &request, .buffer = NULL, .complete_cb = process_enumeration, .user_arg = ENUM_GET_DEVICE_DESC @@ -1503,8 +1537,14 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) { enum_full_complete(); - // Invoke callback if available - if (tuh_mount_cb) tuh_mount_cb(dev_addr); +#if CFG_TUH_HUB + // skip device mount callback for hub + if ( !is_hub_addr(dev_addr) ) +#endif + { + // Invoke callback if available + if (tuh_mount_cb) tuh_mount_cb(dev_addr); + } } } diff --git a/src/host/usbh.h b/src/host/usbh.h index fc059019..7dffcb45 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -46,7 +46,10 @@ typedef bool (*tuh_control_xfer_cb_t)(uint8_t daddr, tuh_control_xfer_t const * struct tuh_control_xfer_s { - tusb_control_request_t request TU_ATTR_ALIGNED(4); + uint8_t ep_addr; + tusb_control_request_t const* setup; + uint32_t actual_len; + uint8_t* buffer; tuh_control_xfer_cb_t complete_cb; uintptr_t user_arg; @@ -104,14 +107,16 @@ static inline bool tuh_ready(uint8_t daddr) return tuh_mounted(daddr) && !tuh_suspended(daddr); } +//--------------------------------------------------------------------+ +// Endpoint Asynchronous (non-blocking) +//--------------------------------------------------------------------+ + // Carry out a control transfer // true on success, false if there is on-going control transfer or incorrect parameters // Blocking if complete callback is NULL, in this case 'user_arg' must contain xfer_result_t variable -bool tuh_control_xfer (uint8_t daddr, tuh_control_xfer_t const* xfer); +bool tuh_control_xfer(uint8_t daddr, tuh_control_xfer_t const* xfer); -// Sync (blocking) version of tuh_control_xfer() -// return transfer result -uint8_t tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t const* xfer, uint32_t timeout_ms); +//bool tuh_edpt_xfer(uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); // Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 @@ -120,6 +125,14 @@ uint8_t tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t const* xfer, uin bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_control_xfer_cb_t complete_cb, uintptr_t user_arg); +//--------------------------------------------------------------------+ +// Endpoint Synchronous (blocking) +//--------------------------------------------------------------------+ + +// Sync (blocking) version of tuh_control_xfer() +// return transfer result +uint8_t tuh_control_xfer_sync(uint8_t daddr, tuh_control_xfer_t const* xfer, uint32_t timeout_ms); + //--------------------------------------------------------------------+ // Descriptors Asynchronous (non-blocking) //--------------------------------------------------------------------+ @@ -201,10 +214,6 @@ uint8_t tuh_descriptor_get_product_string_sync(uint8_t daddr, uint16_t language_ // return transfer result uint8_t tuh_descriptor_get_serial_string_sync(uint8_t daddr, uint16_t language_id, void* buffer, uint16_t len, uint8_t timeout_ms); -//--------------------------------------------------------------------+ -// -//--------------------------------------------------------------------+ - #ifdef __cplusplus } #endif