clean up hub

This commit is contained in:
hathach 2018-12-06 22:47:49 +07:00
parent 7d3ff7aff6
commit 07c3fd5e1e
7 changed files with 78 additions and 118 deletions

View File

@ -83,7 +83,7 @@
// DEVICE CONFIGURATION // DEVICE CONFIGURATION
//-------------------------------------------------------------------- //--------------------------------------------------------------------
#define CFG_TUH_HUB 1 #define CFG_TUH_HUB 1 // not tested
#define CFG_TUH_CDC 1 #define CFG_TUH_CDC 1
#define CFG_TUSB_HOST_HID_KEYBOARD 0 #define CFG_TUSB_HOST_HID_KEYBOARD 0
#define CFG_TUSB_HOST_HID_MOUSE 0 #define CFG_TUSB_HOST_HID_MOUSE 0

View File

@ -142,11 +142,9 @@ void cdch_init(void)
tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX); tu_memclr(cdch_data, sizeof(cdch_data_t)*CFG_TUSB_HOST_DEVICE_MAX);
} }
tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) bool cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length)
{ {
//OSAL_SUBTASK_BEGIN
// TODO change following assert to subtask_assert // TODO change following assert to subtask_assert
if ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL != p_interface_desc->bInterfaceSubClass) return TUSB_ERROR_CDC_UNSUPPORTED_SUBCLASS; if ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL != p_interface_desc->bInterfaceSubClass) return TUSB_ERROR_CDC_UNSUPPORTED_SUBCLASS;
if ( !(tu_within(CDC_COMM_PROTOCOL_ATCOMMAND, p_interface_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) || if ( !(tu_within(CDC_COMM_PROTOCOL_ATCOMMAND, p_interface_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) ||
@ -185,7 +183,7 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
(*p_length) += p_desc[DESC_OFFSET_LEN]; (*p_length) += p_desc[DESC_OFFSET_LEN];
p_desc = descriptor_next(p_desc); p_desc = descriptor_next(p_desc);
TU_ASSERT(pipehandle_is_valid(p_cdc->pipe_notification), TUSB_ERROR_HCD_OPEN_PIPE_FAILED); TU_ASSERT(pipehandle_is_valid(p_cdc->pipe_notification));
} }
//------------- Data Interface (if any) -------------// //------------- Data Interface (if any) -------------//
@ -199,14 +197,14 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
for(uint32_t i=0; i<2; i++) for(uint32_t i=0; i<2; i++)
{ {
tusb_desc_endpoint_t const *p_endpoint = (tusb_desc_endpoint_t const *) p_desc; tusb_desc_endpoint_t const *p_endpoint = (tusb_desc_endpoint_t const *) p_desc;
TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType, TUSB_ERROR_USBH_DESCRIPTOR_CORRUPTED); TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType);
TU_ASSERT(TUSB_XFER_BULK == p_endpoint->bmAttributes.xfer, TUSB_ERROR_USBH_DESCRIPTOR_CORRUPTED); TU_ASSERT(TUSB_XFER_BULK == p_endpoint->bmAttributes.xfer);
pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_IN_MASK ) ? pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_IN_MASK ) ?
&p_cdc->pipe_in : &p_cdc->pipe_out; &p_cdc->pipe_in : &p_cdc->pipe_out;
(*p_pipe_hdl) = hcd_pipe_open(dev_addr, p_endpoint, TUSB_CLASS_CDC); (*p_pipe_hdl) = hcd_pipe_open(dev_addr, p_endpoint, TUSB_CLASS_CDC);
TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED ); TU_ASSERT ( pipehandle_is_valid(*p_pipe_hdl) );
(*p_length) += p_desc[DESC_OFFSET_LEN]; (*p_length) += p_desc[DESC_OFFSET_LEN];
p_desc = descriptor_next( p_desc ); p_desc = descriptor_next( p_desc );
@ -218,7 +216,7 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_
tuh_cdc_mounted_cb(dev_addr); tuh_cdc_mounted_cb(dev_addr);
} }
//OSAL_SUBTASK_END return true;
} }
void cdch_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes) void cdch_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes)

View File

@ -149,10 +149,10 @@ typedef struct {
extern cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX]; // TODO consider to move to cdch internal header file extern cdch_data_t cdch_data[CFG_TUSB_HOST_DEVICE_MAX]; // TODO consider to move to cdch internal header file
void cdch_init(void); void cdch_init(void);
tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT; bool cdch_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT;
void cdch_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes); void cdch_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
void cdch_close(uint8_t dev_addr); void cdch_close(uint8_t dev_addr);
#endif #endif

View File

@ -67,76 +67,53 @@ ATTR_ALIGNED(4) CFG_TUSB_MEM_SECTION STATIC_VAR uint8_t hub_enum_buffer[sizeof(d
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// HUB // HUB
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
tusb_error_t hub_port_clear_feature_subtask(uint8_t hub_addr, uint8_t hub_port, uint8_t feature) bool hub_port_clear_feature_subtask(uint8_t hub_addr, uint8_t hub_port, uint8_t feature)
{ {
tusb_error_t error; TU_ASSERT(HUB_FEATURE_PORT_CONNECTION_CHANGE <= feature && feature <= HUB_FEATURE_PORT_RESET_CHANGE);
OSAL_SUBTASK_BEGIN
STASK_ASSERT(HUB_FEATURE_PORT_CONNECTION_CHANGE <= feature &&
feature <= HUB_FEATURE_PORT_RESET_CHANGE);
//------------- Clear Port Feature request -------------// //------------- Clear Port Feature request -------------//
STASK_INVOKE( TU_ASSERT( usbh_control_xfer_subtask( hub_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER),
usbh_control_xfer_subtask( hub_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER), HUB_REQUEST_CLEAR_FEATURE, feature, hub_port,
HUB_REQUEST_CLEAR_FEATURE, feature, hub_port, 0, NULL ) );
0, NULL ),
error
);
STASK_ASSERT_ERR( error );
//------------- Get Port Status to check if feature is cleared -------------// //------------- Get Port Status to check if feature is cleared -------------//
STASK_INVOKE( TU_ASSERT( usbh_control_xfer_subtask( hub_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER),
usbh_control_xfer_subtask( hub_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER), HUB_REQUEST_GET_STATUS, 0, hub_port,
HUB_REQUEST_GET_STATUS, 0, hub_port, 4, hub_enum_buffer ) );
4, hub_enum_buffer ),
error
);
STASK_ASSERT_ERR( error );
//------------- Check if feature is cleared -------------// //------------- Check if feature is cleared -------------//
hub_port_status_response_t * p_port_status; hub_port_status_response_t * p_port_status;
p_port_status = (hub_port_status_response_t *) hub_enum_buffer; p_port_status = (hub_port_status_response_t *) hub_enum_buffer;
STASK_ASSERT( !BIT_TEST_(p_port_status->status_change.value, feature-16) ); TU_ASSERT( !BIT_TEST_(p_port_status->status_change.value, feature-16) );
OSAL_SUBTASK_END return true;
} }
tusb_error_t hub_port_reset_subtask(uint8_t hub_addr, uint8_t hub_port) bool hub_port_reset_subtask(uint8_t hub_addr, uint8_t hub_port)
{ {
enum { RESET_DELAY = 200 }; // USB specs say only 50ms but many devices require much longer enum { RESET_DELAY = 200 }; // USB specs say only 50ms but many devices require much longer
tusb_error_t error; tusb_error_t error;
OSAL_SUBTASK_BEGIN
//------------- Set Port Reset -------------// //------------- Set Port Reset -------------//
STASK_INVOKE( TU_ASSERT( usbh_control_xfer_subtask( hub_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER),
usbh_control_xfer_subtask( hub_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER),
HUB_REQUEST_SET_FEATURE, HUB_FEATURE_PORT_RESET, hub_port, HUB_REQUEST_SET_FEATURE, HUB_FEATURE_PORT_RESET, hub_port,
0, NULL ), 0, NULL ) );
error
);
STASK_ASSERT_ERR( error );
osal_task_delay(RESET_DELAY); // TODO Hub wait for Status Endpoint on Reset Change osal_task_delay(RESET_DELAY); // TODO Hub wait for Status Endpoint on Reset Change
//------------- Get Port Status to check if port is enabled, powered and reset_change -------------// //------------- Get Port Status to check if port is enabled, powered and reset_change -------------//
STASK_INVOKE( TU_ASSERT( usbh_control_xfer_subtask( hub_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER),
usbh_control_xfer_subtask( hub_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER), HUB_REQUEST_GET_STATUS, 0, hub_port,
HUB_REQUEST_GET_STATUS, 0, hub_port, 4, hub_enum_buffer ) );
4, hub_enum_buffer ),
error
);
STASK_ASSERT_ERR( error );
hub_port_status_response_t * p_port_status; hub_port_status_response_t * p_port_status;
p_port_status = (hub_port_status_response_t *) hub_enum_buffer; p_port_status = (hub_port_status_response_t *) hub_enum_buffer;
STASK_ASSERT ( p_port_status->status_change.reset && p_port_status->status_current.connect_status && TU_ASSERT ( p_port_status->status_change.reset && p_port_status->status_current.connect_status &&
p_port_status->status_current.port_power && p_port_status->status_current.port_enable); p_port_status->status_current.port_power && p_port_status->status_current.port_enable);
OSAL_SUBTASK_END return true;
} }
// can only get the speed RIGHT AFTER hub_port_reset_subtask call // can only get the speed RIGHT AFTER hub_port_reset_subtask call
@ -156,36 +133,28 @@ void hub_init(void)
// hub_enum_sem_hdl = osal_semaphore_create( OSAL_SEM_REF(hub_enum_semaphore) ); // hub_enum_sem_hdl = osal_semaphore_create( OSAL_SEM_REF(hub_enum_semaphore) );
} }
tusb_error_t hub_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) bool hub_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length)
{ {
tusb_error_t error;
OSAL_SUBTASK_BEGIN
// not support multiple TT yet // not support multiple TT yet
if ( p_interface_desc->bInterfaceProtocol > 1 ) return TUSB_ERROR_HUB_FEATURE_NOT_SUPPORTED; if ( p_interface_desc->bInterfaceProtocol > 1 ) return false;
//------------- Open Interrupt Status Pipe -------------// //------------- Open Interrupt Status Pipe -------------//
tusb_desc_endpoint_t const *p_endpoint; tusb_desc_endpoint_t const *p_endpoint;
p_endpoint = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_interface_desc ); p_endpoint = (tusb_desc_endpoint_t const *) descriptor_next( (uint8_t const*) p_interface_desc );
STASK_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType); TU_ASSERT(TUSB_DESC_ENDPOINT == p_endpoint->bDescriptorType);
STASK_ASSERT(TUSB_XFER_INTERRUPT == p_endpoint->bmAttributes.xfer); TU_ASSERT(TUSB_XFER_INTERRUPT == p_endpoint->bmAttributes.xfer);
hub_data[dev_addr-1].pipe_status = hcd_pipe_open(dev_addr, p_endpoint, TUSB_CLASS_HUB); hub_data[dev_addr-1].pipe_status = hcd_pipe_open(dev_addr, p_endpoint, TUSB_CLASS_HUB);
STASK_ASSERT( pipehandle_is_valid(hub_data[dev_addr-1].pipe_status) ); TU_ASSERT( pipehandle_is_valid(hub_data[dev_addr-1].pipe_status) );
hub_data[dev_addr-1].interface_number = p_interface_desc->bInterfaceNumber; hub_data[dev_addr-1].interface_number = p_interface_desc->bInterfaceNumber;
(*p_length) = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t); (*p_length) = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t);
//------------- Get Hub Descriptor -------------// //------------- Get Hub Descriptor -------------//
STASK_INVOKE( TU_ASSERT( usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_DEVICE),
usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_DEVICE), HUB_REQUEST_GET_DESCRIPTOR, 0, 0,
HUB_REQUEST_GET_DESCRIPTOR, 0, 0, sizeof(descriptor_hub_desc_t), hub_enum_buffer ) );
sizeof(descriptor_hub_desc_t), hub_enum_buffer ),
error
);
STASK_ASSERT_ERR(error);
// only care about this field in hub descriptor // only care about this field in hub descriptor
hub_data[dev_addr-1].port_number = ((descriptor_hub_desc_t*) hub_enum_buffer)->bNbrPorts; hub_data[dev_addr-1].port_number = ((descriptor_hub_desc_t*) hub_enum_buffer)->bNbrPorts;
@ -194,18 +163,15 @@ tusb_error_t hub_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_i
static uint8_t i; static uint8_t i;
for(i=1; i <= hub_data[dev_addr-1].port_number; i++) for(i=1; i <= hub_data[dev_addr-1].port_number; i++)
{ {
STASK_INVOKE( TU_ASSERT( usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER),
usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_OUT, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER), HUB_REQUEST_SET_FEATURE, HUB_FEATURE_PORT_POWER, i,
HUB_REQUEST_SET_FEATURE, HUB_FEATURE_PORT_POWER, i, 0, NULL ) );
0, NULL ),
error
);
} }
//------------- Queue the initial Status endpoint transfer -------------// //------------- Queue the initial Status endpoint transfer -------------//
STASK_ASSERT_ERR ( hcd_pipe_xfer(hub_data[dev_addr-1].pipe_status, &hub_data[dev_addr-1].status_change, 1, true) ); TU_ASSERT( TUSB_ERROR_NONE == hcd_pipe_xfer(hub_data[dev_addr-1].pipe_status, &hub_data[dev_addr-1].status_change, 1, true) );
OSAL_SUBTASK_END return true;
} }
// is the response of interrupt endpoint polling // is the response of interrupt endpoint polling

View File

@ -184,8 +184,8 @@ typedef struct {
TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct"); TU_VERIFY_STATIC( sizeof(hub_port_status_response_t) == 4, "size is not correct");
tusb_error_t hub_port_reset_subtask(uint8_t hub_addr, uint8_t hub_port); bool hub_port_reset_subtask(uint8_t hub_addr, uint8_t hub_port);
tusb_error_t hub_port_clear_feature_subtask(uint8_t hub_addr, uint8_t hub_port, uint8_t feature); bool hub_port_clear_feature_subtask(uint8_t hub_addr, uint8_t hub_port, uint8_t feature);
tusb_speed_t hub_port_get_speed(void); tusb_speed_t hub_port_get_speed(void);
tusb_error_t hub_status_pipe_queue(uint8_t dev_addr); tusb_error_t hub_status_pipe_queue(uint8_t dev_addr);
@ -194,10 +194,10 @@ tusb_error_t hub_status_pipe_queue(uint8_t dev_addr);
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
#ifdef _TINY_USB_SOURCE_FILE_ #ifdef _TINY_USB_SOURCE_FILE_
void hub_init(void); void hub_init(void);
tusb_error_t hub_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT; bool hub_open_subtask(uint8_t dev_addr, tusb_desc_interface_t const *p_interface_desc, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT;
void hub_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes); void hub_isr(pipe_handle_t pipe_hdl, xfer_result_t event, uint32_t xferred_bytes);
void hub_close(uint8_t dev_addr); void hub_close(uint8_t dev_addr);
#endif #endif

View File

@ -76,7 +76,7 @@ static host_class_driver_t const usbh_class_drivers[] =
}, },
#endif #endif
#if CFG_TUSB_HOST_CDC #if CFG_TUH_CDC
[TUSB_CLASS_CDC] = { [TUSB_CLASS_CDC] = {
.init = cdch_init, .init = cdch_init,
.open_subtask = cdch_open_subtask, .open_subtask = cdch_open_subtask,
@ -85,7 +85,7 @@ static host_class_driver_t const usbh_class_drivers[] =
}, },
#endif #endif
#if CFG_TUSB_HOST_MSC #if CFG_TUH_MSC
[TUSB_CLASS_MSC] = { [TUSB_CLASS_MSC] = {
.init = msch_init, .init = msch_init,
.open_subtask = msch_open_subtask, .open_subtask = msch_open_subtask,
@ -404,40 +404,37 @@ bool usbh_task_body(void)
else else
{ {
//------------- Get Port Status -------------// //------------- Get Port Status -------------//
STASK_INVOKE( TU_VERIFY_HDLR( usbh_control_xfer_subtask( usbh_devices[0].hub_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER),
usbh_control_xfer_subtask( usbh_devices[0].hub_addr, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_CLASS, TUSB_REQ_RCPT_OTHER), HUB_REQUEST_GET_STATUS, 0, usbh_devices[0].hub_port,
HUB_REQUEST_GET_STATUS, 0, usbh_devices[0].hub_port, 4, enum_data_buffer )
4, enum_data_buffer ), , hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor
error
);
// STASK_ASSERT_ERR( error );
STASK_ASSERT_ERR_HDLR(error, hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor
// Acknowledge Port Connection Change // Acknowledge Port Connection Change
STASK_INVOKE( hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_CONNECTION_CHANGE), error ); hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_CONNECTION_CHANGE);
hub_port_status_response_t * p_port_status; hub_port_status_response_t * p_port_status;
p_port_status = ((hub_port_status_response_t *) enum_data_buffer); p_port_status = ((hub_port_status_response_t *) enum_data_buffer);
if ( ! p_port_status->status_change.connect_status ) STASK_RETURN(TUSB_ERROR_NONE); // only handle connection change if ( ! p_port_status->status_change.connect_status ) return true; // only handle connection change
if ( ! p_port_status->status_current.connect_status ) if ( ! p_port_status->status_current.connect_status )
{ // Disconnection event {
// Disconnection event
usbh_device_unplugged(usbh_devices[0].core_id, usbh_devices[0].hub_addr, usbh_devices[0].hub_port); usbh_device_unplugged(usbh_devices[0].core_id, usbh_devices[0].hub_addr, usbh_devices[0].hub_port);
(void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe (void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe
STASK_RETURN(TUSB_ERROR_NONE); // restart task return true; // restart task
} }
else else
{ // Connection Event {
STASK_INVOKE ( hub_port_reset_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port), error ); // Connection Event
// STASK_ASSERT_ERR( error ); TU_VERIFY_HDLR(hub_port_reset_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port),
STASK_ASSERT_ERR_HDLR(error, hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor
usbh_devices[0].speed = hub_port_get_speed(); usbh_devices[0].speed = hub_port_get_speed();
// Acknowledge Port Reset Change // Acknowledge Port Reset Change
STASK_INVOKE( hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_RESET_CHANGE), error ); hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_RESET_CHANGE);
} }
} }
#endif #endif
@ -446,27 +443,28 @@ bool usbh_task_body(void)
usbh_devices[0].state = TUSB_DEVICE_STATE_ADDRESSED; usbh_devices[0].state = TUSB_DEVICE_STATE_ADDRESSED;
//------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------// //------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------//
// TODO some slow device is observed to fail the very fist controller xfer, can try more times bool is_ok = usbh_control_xfer_subtask(0, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_STANDARD, TUSB_REQ_RCPT_DEVICE),
TU_ASSERT(usbh_control_xfer_subtask(0, bm_request_type(TUSB_DIR_IN, TUSB_REQ_TYPE_STANDARD, TUSB_REQ_RCPT_DEVICE), TUSB_REQ_GET_DESCRIPTOR,
TUSB_REQ_GET_DESCRIPTOR, (TUSB_DESC_DEVICE << 8), 0, 8, enum_data_buffer);
(TUSB_DESC_DEVICE << 8), 0, 8, enum_data_buffer));
//------------- Reset device again before Set Address -------------// //------------- Reset device again before Set Address -------------//
if (usbh_devices[0].hub_addr == 0) if (usbh_devices[0].hub_addr == 0)
{ {
// connected directly to roothub // connected directly to roothub
TU_ASSERT(is_ok); // TODO some slow device is observed to fail the very fist controller xfer, can try more times
hcd_port_reset( usbh_devices[0].core_id ); // reset port after 8 byte descriptor hcd_port_reset( usbh_devices[0].core_id ); // reset port after 8 byte descriptor
osal_task_delay(RESET_DELAY); osal_task_delay(RESET_DELAY);
} }
#if CFG_TUH_HUB #if CFG_TUH_HUB
else else
{ // connected via a hub {
STASK_ASSERT_ERR_HDLR(error, hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor // connected via a hub
STASK_INVOKE ( hub_port_reset_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port), error ); TU_VERIFY_HDLR(is_ok, hub_status_pipe_queue( usbh_devices[0].hub_addr) ); // TODO hub refractor
if ( TUSB_ERROR_NONE == error ) if ( hub_port_reset_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port) )
{ // Acknowledge Port Reset Change if Reset Successful {
STASK_INVOKE( hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_RESET_CHANGE), error ); // Acknowledge Port Reset Change if Reset Successful
hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_RESET_CHANGE);
} }
(void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe (void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe
@ -560,9 +558,7 @@ bool usbh_task_body(void)
static uint16_t length; static uint16_t length;
length = 0; length = 0;
error = usbh_class_drivers[class_index].open_subtask( new_addr, (tusb_desc_interface_t*) p_desc, &length ); if ( usbh_class_drivers[class_index].open_subtask(new_addr, (tusb_desc_interface_t*) p_desc, &length) )
if (error == TUSB_ERROR_NONE)
{ {
TU_ASSERT( length >= sizeof(tusb_desc_interface_t) ); TU_ASSERT( length >= sizeof(tusb_desc_interface_t) );
usbh_devices[new_addr].flag_supported_class |= BIT_(class_index); usbh_devices[new_addr].flag_supported_class |= BIT_(class_index);

View File

@ -65,7 +65,7 @@ typedef enum tusb_interface_status_{
typedef struct { typedef struct {
void (* const init) (void); void (* const init) (void);
tusb_error_t (* const open_subtask)(uint8_t, tusb_desc_interface_t const *, uint16_t*); bool (* const open_subtask)(uint8_t, tusb_desc_interface_t const *, uint16_t*);
void (* const isr) (pipe_handle_t, xfer_result_t, uint32_t); void (* const isr) (pipe_handle_t, xfer_result_t, uint32_t);
void (* const close) (uint8_t); void (* const close) (uint8_t);
} host_class_driver_t; } host_class_driver_t;