mirror of
https://github.com/hathach/tinyusb.git
synced 2025-03-29 01:20:19 +00:00
Hub: Handle hub device status change interrupt
This commit is contained in:
parent
aafea8ef5d
commit
3c7b5dcaff
@ -44,6 +44,7 @@ typedef struct
|
||||
uint8_t status_change; // data from status change interrupt endpoint
|
||||
|
||||
hub_port_status_response_t port_status;
|
||||
hub_status_response_t hub_status;
|
||||
} hub_interface_t;
|
||||
|
||||
CFG_TUSB_MEM_SECTION static hub_interface_t hub_data[CFG_TUH_HUB];
|
||||
@ -314,6 +315,7 @@ static void config_port_power_complete (tuh_xfer_t* xfer)
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
static void hub_port_get_status_complete (tuh_xfer_t* xfer);
|
||||
static void hub_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);
|
||||
|
||||
@ -326,19 +328,31 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32
|
||||
|
||||
hub_interface_t* p_hub = get_itf(dev_addr);
|
||||
|
||||
TU_LOG2(" Port Status Change = 0x%02X\r\n", p_hub->status_change);
|
||||
TU_LOG2(" Hub Status Change = 0x%02X\r\n", p_hub->status_change);
|
||||
|
||||
// Hub ignore bit0 in status change
|
||||
for (uint8_t port=1; port <= p_hub->port_count; port++)
|
||||
// Hub bit 0 is for the hub device events
|
||||
if (tu_bit_test(p_hub->status_change, 0))
|
||||
{
|
||||
if ( tu_bit_test(p_hub->status_change, port) )
|
||||
if (hub_port_get_status(dev_addr, 0, &p_hub->hub_status, hub_get_status_complete, 0) == false)
|
||||
{
|
||||
if (hub_port_get_status(dev_addr, port, &p_hub->port_status, hub_port_get_status_complete, 0) == false)
|
||||
//Hub status control transfer failed, retry
|
||||
hub_edpt_status_xfer(dev_addr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hub bits 1 to n are hub port events
|
||||
for (uint8_t port=1; port <= p_hub->port_count; port++)
|
||||
{
|
||||
if ( tu_bit_test(p_hub->status_change, port) )
|
||||
{
|
||||
//Hub status control transfer failed, retry
|
||||
hub_edpt_status_xfer(dev_addr);
|
||||
if (hub_port_get_status(dev_addr, port, &p_hub->port_status, hub_port_get_status_complete, 0) == false)
|
||||
{
|
||||
//Hub status control transfer failed, retry
|
||||
hub_edpt_status_xfer(dev_addr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -347,6 +361,35 @@ bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32
|
||||
return true;
|
||||
}
|
||||
|
||||
static void hub_clear_feature_complete_stub(tuh_xfer_t* xfer)
|
||||
{
|
||||
TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, );
|
||||
hub_edpt_status_xfer(xfer->daddr);
|
||||
}
|
||||
|
||||
static void hub_get_status_complete (tuh_xfer_t* xfer)
|
||||
{
|
||||
TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, );
|
||||
|
||||
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);
|
||||
TU_ASSERT(port_num == 0 , );
|
||||
|
||||
TU_LOG2("HUB Got hub status, addr = %u, status = %04x\r\n", daddr, p_hub->hub_status.change.value);
|
||||
|
||||
if (p_hub->hub_status.change.local_power_source)
|
||||
{
|
||||
TU_LOG2("HUB Local Power Change, addr = %u\r\n", daddr);
|
||||
hub_port_clear_feature(daddr, port_num, HUB_FEATURE_HUB_LOCAL_POWER_CHANGE, hub_clear_feature_complete_stub, 0);
|
||||
}
|
||||
else if (p_hub->hub_status.change.over_current)
|
||||
{
|
||||
TU_LOG1("HUB Over Current, addr = %u\r\n", daddr);
|
||||
hub_port_clear_feature(daddr, port_num, HUB_FEATURE_HUB_OVER_CURRENT_CHANGE, hub_clear_feature_complete_stub, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void hub_port_get_status_complete (tuh_xfer_t* xfer)
|
||||
{
|
||||
TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, );
|
||||
|
Loading…
x
Reference in New Issue
Block a user