diff options
| author | hathach <[email protected]> | 2013-09-30 16:13:08 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2013-09-30 16:13:08 +0700 |
| commit | 5fb22e3f34db0d9e91df8ca306cc97518bb99792 (patch) | |
| tree | b680b1bf2656504714e4fc204503999990767d80 /tinyusb/host | |
| parent | 821f85cb200c870b874c6681801d20410930dbc5 (diff) | |
refractor hub
Diffstat (limited to 'tinyusb/host')
| -rw-r--r-- | tinyusb/host/hub.c | 56 | ||||
| -rw-r--r-- | tinyusb/host/hub.h | 46 |
2 files changed, 63 insertions, 39 deletions
diff --git a/tinyusb/host/hub.c b/tinyusb/host/hub.c index ec033b868..672ac4c10 100644 --- a/tinyusb/host/hub.c +++ b/tinyusb/host/hub.c @@ -64,15 +64,25 @@ uint8_t hub_enum_buffer[sizeof(descriptor_hub_desc_t)] TUSB_CFG_ATTR_USBRAM; //--------------------------------------------------------------------+ // HUB //--------------------------------------------------------------------+ -tusb_error_t hub_enumerate_subtask(void) +tusb_error_t hub_port_clear_feature_subtask(uint8_t feature) { tusb_error_t error; OSAL_SUBTASK_BEGIN - hub_port_status_response_t * p_port_status; + SUBTASK_ASSERT(HUB_FEATURE_PORT_CONNECTION_CHANGE <= feature && + feature <= HUB_FEATURE_PORT_RESET_CHANGE); - //------------- Get Port Status -------------// + //------------- Clear Port Feature request -------------// + OSAL_SUBTASK_INVOKED_AND_WAIT( + usbh_control_xfer_subtask( usbh_devices[0].hub_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_OTHER), + HUB_REQUEST_CLEAR_FEATURE, feature, usbh_devices[0].hub_port, + 0, NULL ), + error + ); + SUBTASK_ASSERT_STATUS( error ); + + //------------- Get Port Status to check if feature is cleared -------------// OSAL_SUBTASK_INVOKED_AND_WAIT( usbh_control_xfer_subtask( usbh_devices[0].hub_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_OTHER), HUB_REQUEST_GET_STATUS, 0, usbh_devices[0].hub_port, @@ -81,26 +91,22 @@ tusb_error_t hub_enumerate_subtask(void) ); SUBTASK_ASSERT_STATUS( error ); - p_port_status = (hub_port_status_response_t *) hub_enum_buffer; - if ( !p_port_status->status_change.connect_status ) SUBTASK_EXIT(TUSB_ERROR_NONE); // only handle connection change + //------------- Check if feature is cleared -------------// + hub_port_status_response_t * p_port_status = (hub_port_status_response_t *) hub_enum_buffer; + SUBTASK_ASSERT( !BIT_TEST_(p_port_status->status_change.value, feature-16) ); - if ( !p_port_status->status_current.connect_status ) - { // TODO HUB Disconnection + OSAL_SUBTASK_END +} - SUBTASK_EXIT(TUSB_ERROR_NONE); - } +tusb_error_t hub_enumerate_subtask(void) +{ + tusb_error_t error; - // Hub connection - //------------- Clear Hub Port Connect Status Change -------------// - OSAL_SUBTASK_INVOKED_AND_WAIT( - usbh_control_xfer_subtask( usbh_devices[0].hub_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_OTHER), - HUB_REQUEST_CLEAR_FEATURE, HUB_FEATURE_PORT_CONNECTION_CHANGE, usbh_devices[0].hub_port, - 0, NULL ), - error - ); - SUBTASK_ASSERT_STATUS( error ); + OSAL_SUBTASK_BEGIN + + hub_port_status_response_t * p_port_status; - //------------- Get Port Status again to make sure Connect Change is cleared -------------// + //------------- Get Port Status -------------// OSAL_SUBTASK_INVOKED_AND_WAIT( usbh_control_xfer_subtask( usbh_devices[0].hub_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_OTHER), HUB_REQUEST_GET_STATUS, 0, usbh_devices[0].hub_port, @@ -110,7 +116,17 @@ tusb_error_t hub_enumerate_subtask(void) SUBTASK_ASSERT_STATUS( error ); p_port_status = (hub_port_status_response_t *) hub_enum_buffer; - SUBTASK_ASSERT( !p_port_status->status_change.connect_status); // this has to be cleared + if ( !p_port_status->status_change.connect_status ) SUBTASK_EXIT(TUSB_ERROR_NONE); // only handle connection change + + if ( !p_port_status->status_current.connect_status ) + { // TODO HUB Disconnection + + SUBTASK_EXIT(TUSB_ERROR_NONE); + } + + // Acknowledge Port Connection Change + OSAL_SUBTASK_INVOKED_AND_WAIT( hub_port_clear_feature_subtask(HUB_FEATURE_PORT_CONNECTION_CHANGE), error ); + SUBTASK_ASSERT_STATUS( error ); //--------------------------------------------------------------------+ // PORT RESET & WAIT FOR STATUS ENDPOINT & GET STATUS & CLEAR RESET CHANGE diff --git a/tinyusb/host/hub.h b/tinyusb/host/hub.h index cc36ef0a6..445b4e2a3 100644 --- a/tinyusb/host/hub.h +++ b/tinyusb/host/hub.h @@ -144,32 +144,40 @@ enum{ // data in response of HUB_REQUEST_GET_STATUS, wIndex = 0 (hub) typedef struct { - ATTR_PACKED_STRUCT(struct) { - uint16_t local_power_source : 1; - uint16_t over_current : 1; - uint16_t : 14; - }status, status_change; + union{ + ATTR_PACKED_STRUCT(struct) { + uint16_t local_power_source : 1; + uint16_t over_current : 1; + uint16_t : 14; + }; + + uint16_t value; + } status, status_change; } hub_status_response_t; STATIC_ASSERT( sizeof(hub_status_response_t) == 4, "size is not correct"); // data in response of HUB_REQUEST_GET_STATUS, wIndex = Port num typedef struct { - ATTR_PACKED_STRUCT(struct) { - uint16_t connect_status : 1; - uint16_t port_enable : 1; - uint16_t suspend : 1; - uint16_t over_current : 1; - uint16_t reset : 1; + union { + ATTR_PACKED_STRUCT(struct) { + uint16_t connect_status : 1; + uint16_t port_enable : 1; + uint16_t suspend : 1; + uint16_t over_current : 1; + uint16_t reset : 1; + + uint16_t : 3; + uint16_t port_power : 1; + uint16_t low_speed_device_attached : 1; + uint16_t high_speed_device_attached : 1; + uint16_t port_test_mode : 1; + uint16_t port_indicator_control : 1; + uint16_t : 0; + }; - uint16_t : 3; - uint16_t port_power : 1; - uint16_t low_speed_device_attached : 1; - uint16_t high_speed_device_attached : 1; - uint16_t port_test_mode : 1; - uint16_t port_indicator_control : 1; - uint16_t : 0; - }status_current, status_change; + uint16_t value; + } status_current, status_change; } hub_port_status_response_t; STATIC_ASSERT( sizeof(hub_port_status_response_t) == 4, "size is not correct"); |
