summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2023-03-17 15:27:56 +0700
committerGitHub <[email protected]>2023-03-17 15:27:56 +0700
commit16daad81643279ffc951ba11a531877dfee8c872 (patch)
tree8b906cc9e51b0ad614b6982bd0edc9789218ca5f /src
parent96d064e923dbc1c86a247ada0395923667cca468 (diff)
parent511f5be8b34f0a28b20773f2d39bda575f07065f (diff)
Merge pull request #1960 from hathach/fix-host-enumerate-mul-device
Fix host enumerate multiple devices from multiple host controllers
Diffstat (limited to 'src')
-rw-r--r--src/class/cdc/cdc_host.c8
-rw-r--r--src/common/tusb_common.h6
-rw-r--r--src/common/tusb_types.h5
-rw-r--r--src/host/usbh.c57
4 files changed, 40 insertions, 36 deletions
diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c
index e9c3d34cb..011ee49dc 100644
--- a/src/class/cdc/cdc_host.c
+++ b/src/class/cdc/cdc_host.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -97,7 +97,7 @@ static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr)
}
}
- return TUSB_INDEX_INVALID;
+ return TU_INDEX_INVALID_8;
}
@@ -124,7 +124,7 @@ uint8_t tuh_cdc_itf_get_index(uint8_t daddr, uint8_t itf_num)
if (p_cdc->daddr == daddr && p_cdc->bInterfaceNumber == itf_num) return i;
}
- return TUSB_INDEX_INVALID;
+ return TU_INDEX_INVALID_8;
}
bool tuh_cdc_itf_get_info(uint8_t idx, tuh_cdc_itf_info_t* info)
@@ -533,7 +533,7 @@ static void process_cdc_config(tuh_xfer_t* xfer)
uintptr_t const state = xfer->user_data;
uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
uint8_t const idx = tuh_cdc_itf_get_index(xfer->daddr, itf_num);
- TU_ASSERT(idx != TUSB_INDEX_INVALID, );
+ TU_ASSERT(idx != TU_INDEX_INVALID_8, );
switch(state)
{
diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h
index 957491aa9..faccf8726 100644
--- a/src/common/tusb_common.h
+++ b/src/common/tusb_common.h
@@ -75,6 +75,12 @@
#include "tusb_timeout.h" // TODO remove
+enum
+{
+ TU_INDEX_INVALID_8 = 0xFFu
+};
+
+
//--------------------------------------------------------------------+
// Optional API implemented by application if needed
// TODO move to a more ovious place/file
diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h
index 7266a525e..d567bd482 100644
--- a/src/common/tusb_types.h
+++ b/src/common/tusb_types.h
@@ -273,11 +273,6 @@ enum
CONTROL_STAGE_ACK
};
-enum
-{
- TUSB_INDEX_INVALID = 0xff
-};
-
//--------------------------------------------------------------------+
// USB Descriptors
//--------------------------------------------------------------------+
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 12b0ed203..aeab681e9 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -1,4 +1,4 @@
-/*
+/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
@@ -54,8 +54,6 @@
// USBH-HCD common data structure
//--------------------------------------------------------------------+
-// device0 struct must be strictly a subset of normal device struct
-// TODO refactor later
typedef struct
{
// port
@@ -63,15 +61,13 @@ typedef struct
uint8_t hub_addr;
uint8_t hub_port;
uint8_t speed;
+ volatile uint8_t enumerating;
- struct TU_ATTR_PACKED
- {
- volatile uint8_t connected : 1;
- volatile uint8_t addressed : 1;
- volatile uint8_t configured : 1;
- volatile uint8_t suspended : 1;
- };
-
+// struct TU_ATTR_PACKED {
+// uint8_t speed : 4; // packed speed to save footprint
+// volatile uint8_t enumerating : 1;
+// uint8_t TU_RESERVED : 3;
+// };
} usbh_dev0_t;
typedef struct {
@@ -122,10 +118,6 @@ typedef struct {
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
-// Invalid driver ID in itf2drv[] ep2drv[][] mapping
-enum { DRVID_INVALID = 0xFFu };
-enum { CONTROLLER_INVALID = 0xFFu };
-
#if CFG_TUSB_DEBUG >= 2
#define DRIVER_NAME(_name) .name = _name,
#else
@@ -203,7 +195,7 @@ enum { CONFIG_NUM = 1 }; // default to use configuration 1
// sum of end device + hub
#define TOTAL_DEVICES (CFG_TUH_DEVICE_MAX + CFG_TUH_HUB)
-static uint8_t _usbh_controller = CONTROLLER_INVALID;
+static uint8_t _usbh_controller = TU_INDEX_INVALID_8;
// Device with address = 0 for enumeration
static usbh_dev0_t _dev0;
@@ -311,13 +303,13 @@ tusb_speed_t tuh_speed_get (uint8_t dev_addr)
static void clear_device(usbh_device_t* dev)
{
tu_memclr(dev, sizeof(usbh_device_t));
- memset(dev->itf2drv, DRVID_INVALID, sizeof(dev->itf2drv)); // invalid mapping
- memset(dev->ep2drv , DRVID_INVALID, sizeof(dev->ep2drv )); // invalid mapping
+ memset(dev->itf2drv, TU_INDEX_INVALID_8, sizeof(dev->itf2drv)); // invalid mapping
+ memset(dev->ep2drv , TU_INDEX_INVALID_8, sizeof(dev->ep2drv )); // invalid mapping
}
bool tuh_inited(void)
{
- return _usbh_controller != CONTROLLER_INVALID;
+ return _usbh_controller != TU_INDEX_INVALID_8;
}
bool tuh_init(uint8_t controller_id)
@@ -402,10 +394,18 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
switch (event.event_id)
{
case HCD_EVENT_DEVICE_ATTACH:
- // TODO due to the shared _usbh_ctrl_buf, we must complete enumerating
+ // due to the shared _usbh_ctrl_buf, we must complete enumerating
// one device before enumerating another one.
- TU_LOG_USBH("[%u:] USBH DEVICE ATTACH\r\n", event.rhport);
- enum_new_device(&event);
+ if ( _dev0.enumerating )
+ {
+ TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport);
+ osal_queue_send(_usbh_q, &event, in_isr);
+ }else
+ {
+ TU_LOG_USBH("[%u:] USBH DEVICE ATTACH\r\n", event.rhport);
+ _dev0.enumerating = 1;
+ enum_new_device(&event);
+ }
break;
case HCD_EVENT_DEVICE_REMOVE:
@@ -1358,11 +1358,11 @@ static void process_enumeration(tuh_xfer_t* xfer)
dev->configured = 1;
- // Start the Set Configuration process for interfaces (itf = DRVID_INVALID)
+ // Start the Set Configuration process for interfaces (itf = TU_INDEX_INVALID_8)
// 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(daddr, DRVID_INVALID);
+ // TODO use separated API instead of using TU_INDEX_INVALID_8
+ usbh_driver_set_config_complete(daddr, TU_INDEX_INVALID_8);
}
break;
@@ -1562,7 +1562,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur
uint8_t const itf_num = desc_itf->bInterfaceNumber+i;
// Interface number must not be used already
- TU_ASSERT( DRVID_INVALID == dev->itf2drv[itf_num] );
+ TU_ASSERT( TU_INDEX_INVALID_8 == dev->itf2drv[itf_num] );
dev->itf2drv[itf_num] = drv_id;
}
@@ -1596,7 +1596,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
// IAD binding interface such as CDCs should return itf_num + 1 when complete
// with usbh_driver_set_config_complete()
uint8_t const drv_id = dev->itf2drv[itf_num];
- if (drv_id != DRVID_INVALID)
+ if (drv_id != TU_INDEX_INVALID_8)
{
usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id];
TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num);
@@ -1623,6 +1623,9 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
static void enum_full_complete(void)
{
+ // mark enumeration as complete
+ _dev0.enumerating = 0;
+
#if CFG_TUH_HUB
// get next hub status
if (_dev0.hub_addr) hub_edpt_status_xfer(_dev0.hub_addr);