move daddr into xfer struct

This commit is contained in:
hathach 2022-03-18 16:39:35 +07:00
parent 2ff8978dde
commit 8750e3b577
No known key found for this signature in database
GPG Key ID: 2FA891220FBFD581
7 changed files with 132 additions and 99 deletions

View File

@ -115,7 +115,7 @@ static void utf16_to_utf8(uint16_t *temp_buf, size_t buf_len) {
((uint8_t*) temp_buf)[utf8_len] = '\0'; ((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 ) if ( XFER_RESULT_SUCCESS != xfer->result )
{ {
@ -123,6 +123,8 @@ void print_device_descriptor(uint8_t daddr, tuh_xfer_t* xfer)
return; return;
} }
uint8_t const daddr = xfer->daddr;
printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct); printf("Device %u: ID %04x:%04x\r\n", daddr, desc_device.idVendor, desc_device.idProduct);
printf("Device Descriptor:\r\n"); printf("Device Descriptor:\r\n");
printf(" bLength %u\r\n" , desc_device.bLength); printf(" bLength %u\r\n" , desc_device.bLength);

View File

@ -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 = tuh_xfer_t xfer =
{ {
.daddr = dev_addr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = NULL, .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 .user_data = 0
}; };
return tuh_control_xfer(dev_addr, &xfer); return tuh_control_xfer(&xfer);
} }
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+

View File

@ -103,11 +103,12 @@ uint8_t tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance)
return hid_itf->protocol_mode; 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 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 daddr = xfer->daddr;
hidh_interface_t* hid_itf = get_instance(dev_addr, instance); 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) 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) 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 = tuh_xfer_t xfer =
{ {
.daddr = dev_addr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = NULL, .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 .user_data = user_data
}; };
TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); TU_ASSERT( tuh_control_xfer(&xfer) );
return true; 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); 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"); TU_LOG2("HID Set Report complete\r\n");
if (tuh_hid_set_report_complete_cb) if (tuh_hid_set_report_complete_cb)
{ {
uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->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); 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_type = tu_u16_high(xfer->setup->wValue);
uint8_t const report_id = tu_u16_low(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); (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 = tuh_xfer_t xfer =
{ {
.daddr = dev_addr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = report, .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 .user_data = 0
}; };
TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); TU_ASSERT( tuh_control_xfer(&xfer) );
return true; 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 = tuh_xfer_t xfer =
{ {
.daddr = dev_addr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = NULL, .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 .user_data = user_data
}; };
TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); TU_ASSERT( tuh_control_xfer(&xfer) );
return true; 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 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) 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); request.wIndex = tu_htole16((uint16_t) itf_num);
tuh_xfer_t xfer; tuh_xfer_t xfer;
xfer.daddr = dev_addr;
xfer.result = XFER_RESULT_SUCCESS; xfer.result = XFER_RESULT_SUCCESS;
xfer.setup = &request; xfer.setup = &request;
xfer.user_data = CONFG_SET_IDLE; xfer.user_data = CONFG_SET_IDLE;
// fake request to kick-off the set config process // fake request to kick-off the set config process
process_set_config(dev_addr, &xfer); process_set_config(&xfer);
return true; 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 // Stall is a valid response for SET_IDLE, therefore we could ignore its result
if ( xfer->setup->bRequest != HID_REQ_CONTROL_SET_IDLE ) 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, ); TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, );
} }
uintptr_t const state = xfer->user_data; uintptr_t const state = xfer->user_data;
uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->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); uint8_t const daddr = xfer->daddr;
hidh_interface_t* hid_itf = get_instance(dev_addr, instance);
uint8_t const instance = get_instance_id_by_itfnum(daddr, itf_num);
hidh_interface_t* hid_itf = get_instance(daddr, instance);
switch(state) 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 // Idle rate = 0 mean only report when there is changes
const uint16_t idle_rate = 0; 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; 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; break;
case CONFIG_SET_PROTOCOL: 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; break;
case CONFIG_GET_REPORT_DESC: 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); 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 // Driver is mounted without report descriptor
config_driver_mount_complete(dev_addr, instance, NULL, 0); config_driver_mount_complete(daddr, instance, NULL, 0);
}else }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; break;
case CONFIG_COMPLETE: case CONFIG_COMPLETE:
{ {
uint8_t const* desc_report = usbh_get_enum_buf(); 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; break;

View File

@ -358,7 +358,7 @@ bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32
// MSC Enumeration // 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_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_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); 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 = tuh_xfer_t xfer =
{ {
.daddr = dev_addr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = &p_msc->max_lun, .buffer = &p_msc->max_lun,
.complete_cb = config_get_maxlun_complete, .complete_cb = config_get_maxlun_complete,
.user_data = 0 .user_data = 0
}; };
TU_ASSERT(tuh_control_xfer(dev_addr, &xfer)); TU_ASSERT(tuh_control_xfer(&xfer));
return true; 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 // STALL means zero
p_msc->max_lun = (XFER_RESULT_SUCCESS == xfer->result) ? _msch_buffer[0] : 0; 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 // TODO multiple LUN support
TU_LOG2("SCSI Test Unit Ready\r\n"); TU_LOG2("SCSI Test Unit Ready\r\n");
uint8_t const lun = 0; 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) static bool config_test_unit_ready_complete(uint8_t dev_addr, msc_cbw_t const* cbw, msc_csw_t const* csw)

View File

@ -96,6 +96,7 @@ bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature,
tuh_xfer_t xfer = tuh_xfer_t xfer =
{ {
.daddr = hub_addr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = NULL, .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_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; 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 = tuh_xfer_t xfer =
{ {
.daddr = hub_addr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = NULL, .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_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; 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 = tuh_xfer_t xfer =
{ {
.daddr = hub_addr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = resp, .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_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; return true;
} }
@ -225,8 +228,8 @@ bool hub_edpt_status_xfer(uint8_t dev_addr)
// Set Configure // Set Configure
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static void config_set_port_power (uint8_t dev_addr, tuh_xfer_t* xfer); static void config_set_port_power (tuh_xfer_t* xfer);
static void config_port_power_complete (uint8_t dev_addr, 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) 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 = tuh_xfer_t xfer =
{ {
.daddr = dev_addr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = _hub_buffer, .buffer = _hub_buffer,
@ -257,16 +261,17 @@ bool hub_set_config(uint8_t dev_addr, uint8_t itf_num)
.user_data = 0 .user_data = 0
}; };
TU_ASSERT( tuh_control_xfer(dev_addr, &xfer) ); TU_ASSERT( tuh_control_xfer(&xfer) );
return true; 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, ); 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 // only use number of ports in hub descriptor
descriptor_hub_desc_t const* desc_hub = (descriptor_hub_desc_t const*) _hub_buffer; 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 // Set Port Power to be able to detect connection, starting with port 1
uint8_t const hub_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, ); 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) if (xfer->setup->wIndex == p_hub->port_count)
{ {
// All ports are power -> queue notification status endpoint and // All ports are power -> queue notification status endpoint and
// complete the SET CONFIGURATION // 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 }else
{ {
// power next port // power next port
uint8_t const hub_port = (uint8_t) (xfer->setup->wIndex + 1); 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 // Connection Changes
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
static void connection_get_status_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 (uint8_t dev_addr, tuh_xfer_t* xfer); static void connection_clear_conn_change_complete (tuh_xfer_t* xfer);
static void connection_port_reset_complete (uint8_t dev_addr, tuh_xfer_t* xfer); static void connection_port_reset_complete (tuh_xfer_t* xfer);
// callback as response of interrupt endpoint polling // 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) 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; 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, ); 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); uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
// Connection change // 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, ); //TU_VERIFY(port_status.status_current.port_power && port_status.status_current.port_enable, );
// Acknowledge Port Connection Change // 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 }else
{ {
// Other changes are: Enable, Suspend, Over Current, Reset, L1 state // 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 // prepare for next hub status
// TODO continue with status_change, or maybe we can do it again with 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, ); 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); uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
if ( p_hub->port_status.status.connection ) if ( p_hub->port_status.status.connection )
{ {
// Reset port if attach event // 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 }else
{ {
// submit detach event // submit detach event
hcd_event_t event = hcd_event_t event =
{ {
.rhport = usbh_get_rhport(dev_addr), .rhport = usbh_get_rhport(daddr),
.event_id = HCD_EVENT_DEVICE_REMOVE, .event_id = HCD_EVENT_DEVICE_REMOVE,
.connection = .connection =
{ {
.hub_addr = dev_addr, .hub_addr = daddr,
.hub_port = port_num .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, ); 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); uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
// submit attach event // submit attach event
hcd_event_t event = hcd_event_t event =
{ {
.rhport = usbh_get_rhport(dev_addr), .rhport = usbh_get_rhport(daddr),
.event_id = HCD_EVENT_DEVICE_ATTACH, .event_id = HCD_EVENT_DEVICE_ATTACH,
.connection = .connection =
{ {
.hub_addr = dev_addr, .hub_addr = daddr,
.hub_port = port_num .hub_port = port_num
} }
}; };

View File

@ -340,6 +340,7 @@ static bool _get_descriptor(uint8_t daddr, uint8_t type, uint8_t index, uint16_t
tuh_xfer_t xfer = tuh_xfer_t xfer =
{ {
.daddr = daddr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = buffer, .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 .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 blocking, user_data could be pointed to xfer_result
if ( !complete_cb && user_data ) 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 = tuh_xfer_t xfer =
{ {
.daddr = daddr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = buffer, .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 .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 blocking, user_data could be pointed to xfer_result
if ( !complete_cb && user_data ) if ( !complete_cb && user_data )
@ -473,6 +475,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num,
tuh_xfer_t xfer = tuh_xfer_t xfer =
{ {
.daddr = daddr,
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = NULL, .buffer = NULL,
@ -480,7 +483,7 @@ bool tuh_configuration_set(uint8_t daddr, uint8_t config_num,
.user_data = user_data .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 // 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 // update result
*((xfer_result_t*) xfer->user_data) = xfer->result; *((xfer_result_t*) xfer->user_data) = xfer->result;
} }
// TODO timeout_ms is not supported yet // 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 // pre-check to help reducing mutex lock
TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE); 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 // TODO probably better to use semaphore as resource management than mutex
usbh_lock(); usbh_lock();
bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE); 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(); usbh_unlock();
@ -937,13 +954,6 @@ bool tuh_control_xfer (uint8_t daddr, tuh_xfer_t* xfer)
TU_LOG2_VAR(&xfer->setup); TU_LOG2_VAR(&xfer->setup);
TU_LOG2("\r\n"); 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) if (xfer->complete_cb)
{ {
TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) ); 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(); 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"); 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; tusb_control_request_t const request = _ctrl_xfer.request;
tuh_xfer_t xfer_temp = tuh_xfer_t xfer_temp =
{ {
.daddr = daddr,
.ep_addr = 0, .ep_addr = 0,
.result = result, .result = result,
.setup = &request, .setup = &request,
@ -1007,7 +1018,7 @@ static void _xfer_complete(uint8_t dev_addr, xfer_result_t result)
if (xfer_temp.complete_cb) 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; (void) xfer;
return true; return true;
} }
@ -1144,7 +1154,7 @@ static bool parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configur
static void enum_full_complete(void); static void enum_full_complete(void);
// process device enumeration // 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) if (XFER_RESULT_SUCCESS != xfer->result)
{ {
@ -1153,7 +1163,9 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer)
return; return;
} }
uint8_t const daddr = xfer->daddr;
uintptr_t const state = xfer->user_data; uintptr_t const state = xfer->user_data;
switch(state) switch(state)
{ {
#if CFG_TUH_HUB #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: case ENUM_GET_9BYTE_CONFIG_DESC:
{ {
tusb_desc_device_t const * desc_device = (tusb_desc_device_t const*) _usbh_ctrl_buf; 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, ); TU_ASSERT(dev, );
dev->vid = desc_device->idVendor; 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 // Get 9-byte for total length
uint8_t const config_idx = CONFIG_NUM - 1; uint8_t const config_idx = CONFIG_NUM - 1;
TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n"); 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; break;
@ -1292,22 +1304,22 @@ static void process_enumeration(uint8_t dev_addr, tuh_xfer_t* xfer)
// Get full configuration descriptor // Get full configuration descriptor
uint8_t const config_idx = CONFIG_NUM - 1; uint8_t const config_idx = CONFIG_NUM - 1;
TU_LOG2("Get Configuration[0] Descriptor\r\n"); 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; break;
case ENUM_SET_CONFIG: case ENUM_SET_CONFIG:
// Parse configuration & set up drivers // Parse configuration & set up drivers
// Driver open aren't allowed to make any usb transfer yet // 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; break;
case ENUM_CONFIG_DRIVER: case ENUM_CONFIG_DRIVER:
{ {
TU_LOG2("Device configured\r\n"); TU_LOG2("Device configured\r\n");
usbh_device_t* dev = get_device(dev_addr); usbh_device_t* dev = get_device(daddr);
TU_ASSERT(dev, ); TU_ASSERT(dev, );
dev->configured = 1; 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. // 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() // 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 // 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; break;
@ -1347,10 +1359,11 @@ static bool enum_new_device(hcd_event_t* event)
// 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.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(0, &xfer); process_enumeration(&xfer);
} }
#if CFG_TUH_HUB #if CFG_TUH_HUB
@ -1431,6 +1444,7 @@ static bool enum_request_set_addr(void)
tuh_xfer_t xfer = tuh_xfer_t xfer =
{ {
.daddr = 0, // dev0
.ep_addr = 0, .ep_addr = 0,
.setup = &request, .setup = &request,
.buffer = NULL, .buffer = NULL,
@ -1438,8 +1452,7 @@ static bool enum_request_set_addr(void)
.user_data = ENUM_GET_DEVICE_DESC .user_data = ENUM_GET_DEVICE_DESC
}; };
uint8_t const addr0 = 0; TU_ASSERT( tuh_control_xfer(&xfer) );
TU_ASSERT( tuh_control_xfer(addr0, &xfer) );
return true; return true;
} }

View File

@ -42,7 +42,7 @@
struct tuh_xfer_s; struct tuh_xfer_s;
typedef struct tuh_xfer_s tuh_xfer_t; 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 struct tuh_xfer_s
{ {
@ -54,7 +54,7 @@ struct tuh_xfer_s
union 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 uint32_t buflen; // length if not control transfer
}; };
@ -62,7 +62,7 @@ struct tuh_xfer_s
tuh_xfer_cb_t complete_cb; tuh_xfer_cb_t complete_cb;
uintptr_t user_data; 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 // 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, in this case xfer contents will be updated to reflect the result
// Note: blocking if complete callback is NULL. bool tuh_control_xfer(tuh_xfer_t* xfer);
// xfer contents will be updated to reflect the result
bool tuh_control_xfer(uint8_t daddr, tuh_xfer_t* xfer);
// Submit a bulk/interrupt transfer // 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. // 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) // Set Configuration (control transfer)
// config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1 // config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1