From 8750e3b57756e4377bb737c578e2742b653c314c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 18 Mar 2022 16:39:35 +0700 Subject: [PATCH] move daddr into xfer struct --- examples/host/bare_api/src/main.c | 4 +- src/class/cdc/cdc_host.c | 3 +- src/class/hid/hid_host.c | 53 +++++++++++++---------- src/class/msc/msc_host.c | 12 +++--- src/host/hub.c | 70 +++++++++++++++++------------- src/host/usbh.c | 71 ++++++++++++++++++------------- src/host/usbh.h | 18 ++++---- 7 files changed, 132 insertions(+), 99 deletions(-) diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index b472c40c4..e2e0f4ff3 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -115,7 +115,7 @@ static void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) { ((uint8_t*) temp_buf)[utf8_len] = '\0'; } -void print_device_descriptor(uint8_t daddr, tuh_xfer_t* xfer) +void print_device_descriptor(tuh_xfer_t* xfer) { if ( XFER_RESULT_SUCCESS != xfer->result ) { @@ -123,6 +123,8 @@ void print_device_descriptor(uint8_t daddr, tuh_xfer_t* xfer) return; } + uint8_t const daddr = xfer->daddr; + printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); printf("Device Descriptor:\r\n"); printf(" bLength %u\r\n" , desc_device.bLength); diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 2795750ed..f946974e8 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -140,6 +140,7 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xf tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -147,7 +148,7 @@ bool tuh_cdc_set_control_line_state(uint8_t dev_addr, bool dtr, bool rts, tuh_xf .user_data = 0 }; - return tuh_control_xfer(dev_addr, &xfer); + return tuh_control_xfer(&xfer); } //--------------------------------------------------------------------+ diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 0ad917815..fa99b37fe 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -103,11 +103,12 @@ uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance) return hid_itf->protocol_mode; } -static void set_protocol_complete(uint8_t dev_addr, tuh_xfer_t* xfer) +static void set_protocol_complete(tuh_xfer_t* xfer) { 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); + uint8_t const daddr = xfer->daddr; + uint8_t const instance = get_instance_id_by_itfnum(daddr, itf_num); + hidh_interface_t* hid_itf = get_instance(daddr, instance); if (XFER_RESULT_SUCCESS == xfer->result) { @@ -116,7 +117,7 @@ static void set_protocol_complete(uint8_t dev_addr, tuh_xfer_t* xfer) if (tuh_hid_set_protocol_complete_cb) { - tuh_hid_set_protocol_complete_cb(dev_addr, instance, hid_itf->protocol_mode); + tuh_hid_set_protocol_complete_cb(daddr, instance, hid_itf->protocol_mode); } } @@ -141,6 +142,7 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -148,7 +150,7 @@ static bool _hidh_set_protocol(uint8_t dev_addr, uint8_t itf_num, uint8_t protoc .user_data = user_data }; - TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -160,19 +162,19 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) return _hidh_set_protocol(dev_addr, hid_itf->itf_num, protocol, set_protocol_complete, 0); } -static void set_report_complete(uint8_t dev_addr, tuh_xfer_t* xfer) +static void set_report_complete(tuh_xfer_t* xfer) { TU_LOG2("HID Set Report complete\r\n"); if (tuh_hid_set_report_complete_cb) { 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); + uint8_t const instance = get_instance_id_by_itfnum(xfer->daddr, itf_num); 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, + tuh_hid_set_report_complete_cb(xfer->daddr, instance, report_id, report_type, (xfer->result == XFER_RESULT_SUCCESS) ? xfer->setup->wLength : 0); } } @@ -198,6 +200,7 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = report, @@ -205,7 +208,7 @@ bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, u .user_data = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -229,6 +232,7 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -236,7 +240,7 @@ static bool _hidh_set_idle(uint8_t dev_addr, uint8_t itf_num, uint16_t idle_rate .user_data = user_data }; - TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -389,7 +393,7 @@ enum { }; static void config_driver_mount_complete(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len); -static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer); +static void process_set_config(tuh_xfer_t* xfer); bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -397,17 +401,18 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) request.wIndex = tu_htole16((uint16_t) itf_num); tuh_xfer_t xfer; + xfer.daddr = dev_addr; xfer.result = XFER_RESULT_SUCCESS; xfer.setup = &request; xfer.user_data = CONFG_SET_IDLE; // fake request to kick-off the set config process - process_set_config(dev_addr, &xfer); + process_set_config(&xfer); return true; } -static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer) +static void process_set_config(tuh_xfer_t* xfer) { // Stall is a valid response for SET_IDLE, therefore we could ignore its result if ( xfer->setup->bRequest != HID_REQ_CONTROL_SET_IDLE ) @@ -415,10 +420,12 @@ static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer) TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); } - uintptr_t const state = xfer->user_data; - 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); + uintptr_t const state = xfer->user_data; + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + uint8_t const daddr = xfer->daddr; + + uint8_t const instance = get_instance_id_by_itfnum(daddr, itf_num); + hidh_interface_t* hid_itf = get_instance(daddr, instance); switch(state) { @@ -427,12 +434,12 @@ static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer) // Idle rate = 0 mean only report when there is changes const uint16_t idle_rate = 0; const uintptr_t next_state = (hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE) ? CONFIG_SET_PROTOCOL : CONFIG_GET_REPORT_DESC; - _hidh_set_idle(dev_addr, itf_num, idle_rate, process_set_config, next_state); + _hidh_set_idle(daddr, itf_num, idle_rate, process_set_config, next_state); } break; case CONFIG_SET_PROTOCOL: - _hidh_set_protocol(dev_addr, hid_itf->itf_num, HID_PROTOCOL_BOOT, process_set_config, CONFIG_GET_REPORT_DESC); + _hidh_set_protocol(daddr, hid_itf->itf_num, HID_PROTOCOL_BOOT, process_set_config, CONFIG_GET_REPORT_DESC); break; case CONFIG_GET_REPORT_DESC: @@ -443,19 +450,19 @@ static void process_set_config(uint8_t dev_addr, tuh_xfer_t* xfer) TU_LOG2("HID Skip Report Descriptor since it is too large %u bytes\r\n", hid_itf->report_desc_len); // Driver is mounted without report descriptor - config_driver_mount_complete(dev_addr, instance, NULL, 0); + config_driver_mount_complete(daddr, instance, NULL, 0); }else { - tuh_descriptor_get_hid_report(dev_addr, itf_num, hid_itf->report_desc_type, 0, usbh_get_enum_buf(), hid_itf->report_desc_len, process_set_config, CONFIG_COMPLETE); + tuh_descriptor_get_hid_report(daddr, itf_num, hid_itf->report_desc_type, 0, usbh_get_enum_buf(), hid_itf->report_desc_len, process_set_config, CONFIG_COMPLETE); } break; case CONFIG_COMPLETE: { uint8_t const* desc_report = usbh_get_enum_buf(); - uint16_t const desc_len = xfer->setup->wLength; + uint16_t const desc_len = tu_le16toh(xfer->setup->wLength); - config_driver_mount_complete(dev_addr, instance, desc_report, desc_len); + config_driver_mount_complete(daddr, instance, desc_report, desc_len); } break; diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 5a34f2d56..06af781f5 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -358,7 +358,7 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 // MSC Enumeration //--------------------------------------------------------------------+ -static void config_get_maxlun_complete (uint8_t dev_addr, tuh_xfer_t* xfer); +static void config_get_maxlun_complete (tuh_xfer_t* xfer); static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_request_sense_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); static bool config_read_capacity_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw); @@ -421,20 +421,22 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num) tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = &p_msc->max_lun, .complete_cb = config_get_maxlun_complete, .user_data = 0 }; - TU_ASSERT(tuh_control_xfer(dev_addr, &xfer)); + TU_ASSERT(tuh_control_xfer(&xfer)); return true; } -static void config_get_maxlun_complete (uint8_t dev_addr, tuh_xfer_t* xfer) +static void config_get_maxlun_complete (tuh_xfer_t* xfer) { - msch_interface_t* p_msc = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + msch_interface_t* p_msc = get_itf(daddr); // STALL means zero p_msc->max_lun = (XFER_RESULT_SUCCESS == xfer->result) ? _msch_buffer[0] : 0; @@ -443,7 +445,7 @@ static void config_get_maxlun_complete (uint8_t dev_addr, tuh_xfer_t* xfer) // TODO multiple LUN support TU_LOG2("SCSI Test Unit Ready\r\n"); uint8_t const lun = 0; - tuh_msc_test_unit_ready(dev_addr, lun, config_test_unit_ready_complete); + tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete); } static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw) diff --git a/src/host/hub.c b/src/host/hub.c index ac24988d8..da4f6fe3a 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -96,6 +96,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_xfer_t xfer = { + .daddr = hub_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -104,7 +105,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, }; TU_LOG2("HUB Clear Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer(hub_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -127,6 +128,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_xfer_t xfer = { + .daddr = hub_addr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -135,7 +137,7 @@ bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, }; TU_LOG2("HUB Set Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer(hub_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -158,6 +160,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, tuh_xfer_t xfer = { + .daddr = hub_addr, .ep_addr = 0, .setup = &request, .buffer = resp, @@ -166,7 +169,7 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp, }; TU_LOG2("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port); - TU_ASSERT( tuh_control_xfer( hub_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } @@ -225,8 +228,8 @@ bool hub_edpt_status_xfer(uint8_t dev_addr) // Set Configure //--------------------------------------------------------------------+ -static void config_set_port_power (uint8_t dev_addr, tuh_xfer_t* xfer); -static void config_port_power_complete (uint8_t dev_addr, tuh_xfer_t* xfer); +static void config_set_port_power (tuh_xfer_t* xfer); +static void config_port_power_complete (tuh_xfer_t* xfer); bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) { @@ -250,6 +253,7 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) tuh_xfer_t xfer = { + .daddr = dev_addr, .ep_addr = 0, .setup = &request, .buffer = _hub_buffer, @@ -257,16 +261,17 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num) .user_data = 0 }; - TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } -static void config_set_port_power (uint8_t dev_addr, tuh_xfer_t* xfer) +static void config_set_port_power (tuh_xfer_t* xfer) { TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); - hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); // only use number of ports in hub descriptor descriptor_hub_desc_t const* desc_hub = (descriptor_hub_desc_t const*) _hub_buffer; @@ -276,26 +281,28 @@ static void config_set_port_power (uint8_t dev_addr, tuh_xfer_t* xfer) // Set Port Power to be able to detect connection, starting with port 1 uint8_t const hub_port = 1; - hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); + hub_port_set_feature(daddr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } -static void config_port_power_complete (uint8_t dev_addr, tuh_xfer_t* xfer) +static void config_port_power_complete (tuh_xfer_t* xfer) { TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, ); - hub_interface_t* p_hub = get_itf(dev_addr); + + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); if (xfer->setup->wIndex == p_hub->port_count) { // All ports are power -> queue notification status endpoint and // complete the SET CONFIGURATION - TU_ASSERT( usbh_edpt_xfer(dev_addr, p_hub->ep_in, &p_hub->status_change, 1), ); + TU_ASSERT( usbh_edpt_xfer(daddr, p_hub->ep_in, &p_hub->status_change, 1), ); - usbh_driver_set_config_complete(dev_addr, p_hub->itf_num); + usbh_driver_set_config_complete(daddr, p_hub->itf_num); }else { // power next port uint8_t const hub_port = (uint8_t) (xfer->setup->wIndex + 1); - hub_port_set_feature(dev_addr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); + hub_port_set_feature(daddr, hub_port, HUB_FEATURE_PORT_POWER, config_port_power_complete, 0); } } @@ -303,9 +310,9 @@ static void config_port_power_complete (uint8_t dev_addr, tuh_xfer_t* xfer) // Connection Changes //--------------------------------------------------------------------+ -static void connection_get_status_complete (uint8_t dev_addr, tuh_xfer_t* xfer); -static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_xfer_t* xfer); -static void connection_port_reset_complete (uint8_t dev_addr, tuh_xfer_t* xfer); +static void connection_get_status_complete (tuh_xfer_t* xfer); +static void connection_clear_conn_change_complete (tuh_xfer_t* xfer); +static void connection_port_reset_complete (tuh_xfer_t* xfer); // callback as response of interrupt endpoint polling bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) @@ -333,11 +340,12 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32 return true; } -static void connection_get_status_complete (uint8_t dev_addr, tuh_xfer_t* xfer) +static void connection_get_status_complete (tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); - hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); // Connection change @@ -347,7 +355,7 @@ static void connection_get_status_complete (uint8_t dev_addr, tuh_xfer_t* xfer) //TU_VERIFY(port_status.status_current.port_power && port_status.status_current.port_enable, ); // Acknowledge Port Connection Change - hub_port_clear_feature(dev_addr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, connection_clear_conn_change_complete, 0); + hub_port_clear_feature(daddr, port_num, HUB_FEATURE_PORT_CONNECTION_CHANGE, connection_clear_conn_change_complete, 0); }else { // Other changes are: Enable, Suspend, Over Current, Reset, L1 state @@ -355,31 +363,32 @@ static void connection_get_status_complete (uint8_t dev_addr, tuh_xfer_t* xfer) // prepare for next hub status // TODO continue with status_change, or maybe we can do it again with status - hub_edpt_status_xfer(dev_addr); + hub_edpt_status_xfer(daddr); } } -static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_xfer_t* xfer) +static void connection_clear_conn_change_complete (tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); - hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + hub_interface_t* p_hub = get_itf(daddr); uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); if ( p_hub->port_status.status.connection ) { // Reset port if attach event - hub_port_reset(dev_addr, port_num, connection_port_reset_complete, 0); + hub_port_reset(daddr, port_num, connection_port_reset_complete, 0); }else { // submit detach event hcd_event_t event = { - .rhport = usbh_get_rhport(dev_addr), + .rhport = usbh_get_rhport(daddr), .event_id = HCD_EVENT_DEVICE_REMOVE, .connection = { - .hub_addr = dev_addr, + .hub_addr = daddr, .hub_port = port_num } }; @@ -388,21 +397,22 @@ static void connection_clear_conn_change_complete (uint8_t dev_addr, tuh_xfer_t* } } -static void connection_port_reset_complete (uint8_t dev_addr, tuh_xfer_t* xfer) +static void connection_port_reset_complete (tuh_xfer_t* xfer) { TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, ); - // hub_interface_t* p_hub = get_itf(dev_addr); + uint8_t const daddr = xfer->daddr; + // hub_interface_t* p_hub = get_itf(daddr); uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); // submit attach event hcd_event_t event = { - .rhport = usbh_get_rhport(dev_addr), + .rhport = usbh_get_rhport(daddr), .event_id = HCD_EVENT_DEVICE_ATTACH, .connection = { - .hub_addr = dev_addr, + .hub_addr = daddr, .hub_port = port_num } }; diff --git a/src/host/usbh.c b/src/host/usbh.c index c801707d9..36774d3dc 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -340,6 +340,7 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t tuh_xfer_t xfer = { + .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = buffer, @@ -347,7 +348,7 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t .user_data = user_data }; - bool const ret = tuh_control_xfer(daddr, &xfer); + bool const ret = tuh_control_xfer(&xfer); // if blocking, user_data could be pointed to xfer_result if ( !complete_cb && user_data ) @@ -434,6 +435,7 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ tuh_xfer_t xfer = { + .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = buffer, @@ -441,7 +443,7 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_ .user_data = user_data }; - bool const ret = tuh_control_xfer(daddr, &xfer); + bool const ret = tuh_control_xfer(&xfer); // if blocking, user_data could be pointed to xfer_result if ( !complete_cb && user_data ) @@ -473,6 +475,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, tuh_xfer_t xfer = { + .daddr = daddr, .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -480,7 +483,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num, .user_data = user_data }; - return tuh_control_xfer(daddr, &xfer); + return tuh_control_xfer(&xfer); } //--------------------------------------------------------------------+ @@ -909,24 +912,38 @@ bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) // Control transfer //--------------------------------------------------------------------+ -static void _control_blocking_complete_cb(uint8_t daddr, tuh_xfer_t* xfer) +static void _control_blocking_complete_cb(tuh_xfer_t* xfer) { - (void) daddr; // update result *((xfer_result_t*) xfer->user_data) = xfer->result; } // TODO timeout_ms is not supported yet -bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) +bool tuh_control_xfer (tuh_xfer_t* xfer) { + // EP0 with setup packet + TU_VERIFY(xfer->ep_addr == 0 && xfer->setup); + // pre-check to help reducing mutex lock TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); + uint8_t const daddr = xfer->daddr; + // TODO probably better to use semaphore as resource management than mutex usbh_lock(); bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); - if (is_idle) _ctrl_xfer.stage = CONTROL_STAGE_SETUP; + if (is_idle) + { + _ctrl_xfer.stage = CONTROL_STAGE_SETUP; + _ctrl_xfer.daddr = daddr; + _ctrl_xfer.actual_len = 0; + + _ctrl_xfer.request = (*xfer->setup); + _ctrl_xfer.buffer = xfer->buffer; + _ctrl_xfer.complete_cb = xfer->complete_cb; + _ctrl_xfer.user_data = xfer->user_data; + } usbh_unlock(); @@ -937,13 +954,6 @@ bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer) TU_LOG2_VAR(&xfer->setup); TU_LOG2("\r\n"); - _ctrl_xfer.actual_len = 0; - _ctrl_xfer.daddr = daddr; - _ctrl_xfer.request = (*xfer->setup); - _ctrl_xfer.buffer = xfer->buffer; - _ctrl_xfer.complete_cb = xfer->complete_cb; - _ctrl_xfer.user_data = xfer->user_data; - if (xfer->complete_cb) { TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); @@ -984,7 +994,7 @@ TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage) usbh_unlock(); } -static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) +static void _xfer_complete(uint8_t daddr, xfer_result_t result) { TU_LOG2("\r\n"); @@ -992,6 +1002,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) tusb_control_request_t const request = _ctrl_xfer.request; tuh_xfer_t xfer_temp = { + .daddr = daddr, .ep_addr = 0, .result = result, .setup = &request, @@ -1007,7 +1018,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result) if (xfer_temp.complete_cb) { - xfer_temp.complete_cb(dev_addr, &xfer_temp); + xfer_temp.complete_cb(&xfer_temp); } } @@ -1066,9 +1077,8 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result // //--------------------------------------------------------------------+ -bool tuh_edpt_xfer(uint8_t daddr, tuh_xfer_t* xfer) +bool tuh_edpt_xfer(tuh_xfer_t* xfer) { - (void) daddr; (void) xfer; return true; } @@ -1144,7 +1154,7 @@ static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configur static void enum_full_complete(void); // process device enumeration -static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) +static void process_enumeration(tuh_xfer_t* xfer) { if (XFER_RESULT_SUCCESS != xfer->result) { @@ -1153,7 +1163,9 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) return; } + uint8_t const daddr = xfer->daddr; uintptr_t const state = xfer->user_data; + switch(state) { #if CFG_TUH_HUB @@ -1261,7 +1273,7 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) case ENUM_GET_9BYTE_CONFIG_DESC: { tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; - usbh_device_t* dev = get_device(dev_addr); + usbh_device_t* dev = get_device(daddr); TU_ASSERT(dev, ); dev->vid = desc_device->idVendor; @@ -1275,7 +1287,7 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) // Get 9-byte for total length uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC), ); + TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC), ); } break; @@ -1292,22 +1304,22 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) // Get full configuration descriptor uint8_t const config_idx = CONFIG_NUM - 1; TU_LOG2("Get Configuration[0] Descriptor\r\n"); - TU_ASSERT( tuh_descriptor_get_configuration(dev_addr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG), ); + TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG), ); } break; case ENUM_SET_CONFIG: // Parse configuration & set up drivers // Driver open aren't allowed to make any usb transfer yet - TU_ASSERT( parse_configuration_descriptor(dev_addr, (tusb_desc_configuration_t*) _usbh_ctrl_buf), ); + TU_ASSERT( parse_configuration_descriptor(daddr, (tusb_desc_configuration_t*) _usbh_ctrl_buf), ); - TU_ASSERT( tuh_configuration_set(dev_addr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER), ); + TU_ASSERT( tuh_configuration_set(daddr, CONFIG_NUM, process_enumeration, ENUM_CONFIG_DRIVER), ); break; case ENUM_CONFIG_DRIVER: { TU_LOG2("Device configured\r\n"); - usbh_device_t* dev = get_device(dev_addr); + usbh_device_t* dev = get_device(daddr); TU_ASSERT(dev, ); dev->configured = 1; @@ -1316,7 +1328,7 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer) // Since driver can perform control transfer within its set_config, this is done asynchronously. // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() // TODO use separated API instead of using DRVID_INVALID - usbh_driver_set_config_complete(dev_addr, DRVID_INVALID); + usbh_driver_set_config_complete(daddr, DRVID_INVALID); } break; @@ -1347,10 +1359,11 @@ static bool enum_new_device(hcd_event_t* event) // fake transfer to kick-off the enumeration process tuh_xfer_t xfer; + xfer.daddr = 0; xfer.result = XFER_RESULT_SUCCESS; xfer.user_data = ENUM_ADDR0_DEVICE_DESC; - process_enumeration(0, &xfer); + process_enumeration(&xfer); } #if CFG_TUH_HUB @@ -1431,6 +1444,7 @@ static bool enum_request_set_addr(void) tuh_xfer_t xfer = { + .daddr = 0, // dev0 .ep_addr = 0, .setup = &request, .buffer = NULL, @@ -1438,8 +1452,7 @@ static bool enum_request_set_addr(void) .user_data = ENUM_GET_DEVICE_DESC }; - uint8_t const addr0 = 0; - TU_ASSERT( tuh_control_xfer(addr0, &xfer) ); + TU_ASSERT( tuh_control_xfer(&xfer) ); return true; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 21ef86d5d..f79c5cdc8 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -42,7 +42,7 @@ struct tuh_xfer_s; typedef struct tuh_xfer_s tuh_xfer_t; -typedef void (*tuh_xfer_cb_t)(uint8_t daddr, tuh_xfer_t* xfer); +typedef void (*tuh_xfer_cb_t)(tuh_xfer_t* xfer); struct tuh_xfer_s { @@ -54,7 +54,7 @@ struct tuh_xfer_s union { - tusb_control_request_t const* setup; // setup packet if control transfer + tusb_control_request_t const* setup; // setup packet pointer if control transfer uint32_t buflen; // length if not control transfer }; @@ -62,7 +62,7 @@ struct tuh_xfer_s tuh_xfer_cb_t complete_cb; uintptr_t user_data; - uint32_t timeout_ms; + uint32_t timeout_ms; // place holder, not supported yet }; //--------------------------------------------------------------------+ @@ -118,19 +118,17 @@ static inline bool tuh_ready(uint8_t daddr) } //--------------------------------------------------------------------+ -// Endpoint Asynchronous (non-blocking) +// Transfer API //--------------------------------------------------------------------+ // Submit a control transfer -// true on success, false if there is on-going control transfer or incorrect parameters -// Note: blocking if complete callback is NULL. -// xfer contents will be updated to reflect the result -bool tuh_control_xfer(uint8_t daddr, tuh_xfer_t* xfer); +// Note: blocking if complete callback is NULL, in this case xfer contents will be updated to reflect the result +bool tuh_control_xfer(tuh_xfer_t* xfer); // Submit a bulk/interrupt transfer -// true on success, false if there is on-going control transfer or incorrect parameters +// xfer memory must exist until transfer is complete. // Note: blocking if complete callback is NULL. -bool tuh_edpt_xfer(uint8_t daddr, tuh_xfer_t* xfer); +bool tuh_edpt_xfer(tuh_xfer_t* xfer); // Set Configuration (control transfer) // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1