summaryrefslogtreecommitdiff
path: root/src/host
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2022-12-22 21:29:00 +0700
committerGitHub <[email protected]>2022-12-22 21:29:00 +0700
commit2777df411f23c7105568d73c92dc496dd2a9d97e (patch)
treed753c8914f314ec456544232437044c811a9cebd /src/host
parent97984b4203c4b14499d5a99361823774a49c3afe (diff)
parent396716cc2c29b151556d554c560307afcadd7252 (diff)
Merge pull request #1809 from hathach/host-cdc
Support Host CDC
Diffstat (limited to 'src/host')
-rw-r--r--src/host/usbh.c102
-rw-r--r--src/host/usbh_classdriver.h5
2 files changed, 62 insertions, 45 deletions
diff --git a/src/host/usbh.c b/src/host/usbh.c
index ca42a523c..af1e67d4d 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -30,7 +30,6 @@
#include "host/hcd.h"
#include "tusb.h"
-#include "common/tusb_private.h"
#include "host/usbh_classdriver.h"
#include "hub.h"
@@ -46,8 +45,10 @@
#define CFG_TUH_INTERFACE_MAX 8
#endif
-// Debug level of USBD
-#define USBH_DBG_LVL 2
+// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message
+#define USBH_DEBUG 2
+
+#define TU_LOG_USBH(...) TU_LOG(USBH_DEBUG, __VA_ARGS__)
//--------------------------------------------------------------------+
// USBH-HCD common data structure
@@ -324,11 +325,13 @@ bool tuh_init(uint8_t controller_id)
// skip if already initialized
if ( tuh_inited() ) return true;
- TU_LOG2("USBH init on controller %u\r\n", controller_id);
- TU_LOG2_INT(sizeof(usbh_device_t));
- TU_LOG2_INT(sizeof(hcd_event_t));
- TU_LOG2_INT(sizeof(_ctrl_xfer));
- TU_LOG2_INT(sizeof(tuh_xfer_t));
+ TU_LOG_USBH("USBH init on controller %u\r\n", controller_id);
+ TU_LOG_INT(USBH_DEBUG, sizeof(usbh_device_t));
+ TU_LOG_INT(USBH_DEBUG, sizeof(hcd_event_t));
+ TU_LOG_INT(USBH_DEBUG, sizeof(_ctrl_xfer));
+ TU_LOG_INT(USBH_DEBUG, sizeof(tuh_xfer_t));
+ TU_LOG_INT(USBH_DEBUG, sizeof(tu_fifo_t));
+ TU_LOG_INT(USBH_DEBUG, sizeof(tu_edpt_stream_t));
// Event queue
_usbh_q = osal_queue_create( &_usbh_qdef );
@@ -353,7 +356,7 @@ bool tuh_init(uint8_t controller_id)
// Class drivers
for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++)
{
- TU_LOG2("%s init\r\n", usbh_class_drivers[drv_id].name);
+ TU_LOG_USBH("%s init\r\n", usbh_class_drivers[drv_id].name);
usbh_class_drivers[drv_id].init();
}
@@ -401,12 +404,12 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
case HCD_EVENT_DEVICE_ATTACH:
// TODO due to the shared _usbh_ctrl_buf, we must complete enumerating
// one device before enumerating another one.
- TU_LOG2("[%u:] USBH DEVICE ATTACH\r\n", event.rhport);
+ TU_LOG_USBH("[%u:] USBH DEVICE ATTACH\r\n", event.rhport);
enum_new_device(&event);
break;
case HCD_EVENT_DEVICE_REMOVE:
- TU_LOG2("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port);
+ TU_LOG_USBH("[%u:%u:%u] USBH DEVICE REMOVED\r\n", event.rhport, event.connection.hub_addr, event.connection.hub_port);
process_device_unplugged(event.rhport, event.connection.hub_addr, event.connection.hub_port);
#if CFG_TUH_HUB
@@ -425,7 +428,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const ep_dir = tu_edpt_dir(ep_addr);
- TU_LOG2("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);
+ TU_LOG_USBH("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);
if (event.dev_addr == 0)
{
@@ -449,7 +452,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
uint8_t drv_id = dev->ep2drv[epnum][ep_dir];
if(drv_id < USBH_CLASS_DRIVER_COUNT)
{
- TU_LOG2("%s xfer callback\r\n", usbh_class_drivers[drv_id].name);
+ TU_LOG_USBH("%s xfer callback\r\n", usbh_class_drivers[drv_id].name);
usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, event.xfer_complete.result, event.xfer_complete.len);
}
else
@@ -539,9 +542,11 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
TU_VERIFY(is_idle);
const uint8_t rhport = usbh_get_rhport(daddr);
- TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request");
- TU_LOG2_VAR(xfer->setup);
- TU_LOG2("\r\n");
+ TU_LOG_USBH("[%u:%u] %s: ", rhport, daddr,
+ (xfer->setup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ?
+ tu_str_std_request[xfer->setup->bRequest] : "Class Request");
+ TU_LOG_PTR(USBH_DEBUG, xfer->setup);
+ TU_LOG_USBH("\r\n");
if (xfer->complete_cb)
{
@@ -585,7 +590,7 @@ TU_ATTR_ALWAYS_INLINE static inline void _set_control_xfer_stage(uint8_t stage)
static void _xfer_complete(uint8_t daddr, xfer_result_t result)
{
- TU_LOG2("\r\n");
+ TU_LOG_USBH("\r\n");
// duplicate xfer since user can execute control transfer within callback
tusb_control_request_t const request = _ctrl_xfer.request;
@@ -618,7 +623,11 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
if (XFER_RESULT_SUCCESS != result)
{
- TU_LOG1("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED");
+ TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes);
+ #if CFG_TUSB_DEBUG == 1
+ TU_LOG1_PTR(request);
+ TU_LOG1("\r\n");
+ #endif
// terminate transfer if any stage failed
_xfer_complete(dev_addr, result);
@@ -639,8 +648,8 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
case CONTROL_STAGE_DATA:
if (request->wLength)
{
- TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr);
- TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2);
+ TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr);
+ TU_LOG_MEM(USBH_DEBUG, _ctrl_xfer.buffer, xferred_bytes, 2);
}
_ctrl_xfer.actual_len = (uint16_t) xferred_bytes;
@@ -756,7 +765,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b
uint8_t const dir = tu_edpt_dir(ep_addr);
tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir];
- TU_LOG2(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes);
+ TU_LOG_USBH(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes);
// Attempt to transfer on a busy endpoint, sound like an race condition !
TU_ASSERT(ep_state->busy == 0);
@@ -772,7 +781,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b
if ( hcd_edpt_xfer(dev->rhport, dev_addr, ep_addr, buffer, total_bytes) )
{
- TU_LOG2("OK\r\n");
+ TU_LOG_USBH("OK\r\n");
return true;
}else
{
@@ -787,7 +796,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b
static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size)
{
- TU_LOG2("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size);
+ TU_LOG_USBH("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size);
tusb_desc_endpoint_t ep0_desc =
{
@@ -956,7 +965,7 @@ bool tuh_descriptor_get_serial_string(uint8_t daddr, uint16_t language_id, void*
bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_type, uint8_t index, void* buffer, uint16_t len,
tuh_xfer_cb_t complete_cb, uintptr_t user_data)
{
- TU_LOG2("HID Get Report Descriptor\r\n");
+ TU_LOG_USBH("HID Get Report Descriptor\r\n");
tusb_control_request_t const request =
{
.bmRequestType_bit =
@@ -995,7 +1004,7 @@ bool tuh_descriptor_get_hid_report(uint8_t daddr, uint8_t itf_num, uint8_t desc_
bool tuh_configuration_set(uint8_t daddr, uint8_t config_num,
tuh_xfer_cb_t complete_cb, uintptr_t user_data)
{
- TU_LOG2("Set Configuration = %d\r\n", config_num);
+ TU_LOG_USBH("Set Configuration = %d\r\n", config_num);
tusb_control_request_t const request =
{
@@ -1099,11 +1108,11 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h
(hub_port == 0 || dev->hub_port == hub_port) && // hub_port = 0 means all devices of downstream hub
dev->connected)
{
- TU_LOG2(" Address = %u\r\n", dev_addr);
+ TU_LOG_USBH(" Address = %u\r\n", dev_addr);
if (is_hub_addr(dev_addr))
{
- TU_LOG(USBH_DBG_LVL, "HUB address = %u is unmounted\r\n", dev_addr);
+ TU_LOG(USBH_DEBUG, "HUB address = %u is unmounted\r\n", dev_addr);
// If the device itself is a usb hub, unplug downstream devices.
// FIXME un-roll recursive calls to prevent potential stack overflow
process_device_unplugged(rhport, dev_addr, 0);
@@ -1116,7 +1125,7 @@ static void process_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t h
// Close class driver
for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++)
{
- TU_LOG2("%s close\r\n", usbh_class_drivers[drv_id].name);
+ TU_LOG_USBH("%s close\r\n", usbh_class_drivers[drv_id].name);
usbh_class_drivers[drv_id].close(dev_addr);
}
@@ -1241,7 +1250,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
TU_ASSERT( usbh_edpt_control_open(addr0, 8), );
// Get first 8 bytes of device descriptor for Control Endpoint size
- TU_LOG2("Get 8 byte of Device Descriptor\r\n");
+ TU_LOG_USBH("Get 8 byte of Device Descriptor\r\n");
TU_ASSERT(tuh_descriptor_get_device(addr0, _usbh_ctrl_buf, 8, process_enumeration, ENUM_SET_ADDR), );
}
break;
@@ -1250,7 +1259,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
case ENUM_RESET_2:
// TODO not used by now, but may be needed for some devices !?
// Reset device again before Set Address
- TU_LOG2("Port reset2 \r\n");
+ TU_LOG_USBH("Port reset2 \r\n");
if (_dev0.hub_addr == 0)
{
// connected directly to roothub
@@ -1268,7 +1277,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
break;
}
#endif
- __attribute__((fallthrough));
+ TU_ATTR_FALLTHROUGH;
#endif
case ENUM_SET_ADDR:
@@ -1290,7 +1299,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
TU_ASSERT( usbh_edpt_control_open(new_addr, new_dev->ep0_size), );
// Get full device descriptor
- TU_LOG2("Get Device Descriptor\r\n");
+ TU_LOG_USBH("Get Device Descriptor\r\n");
TU_ASSERT(tuh_descriptor_get_device(new_addr, _usbh_ctrl_buf, sizeof(tusb_desc_device_t), process_enumeration, ENUM_GET_9BYTE_CONFIG_DESC), );
}
break;
@@ -1311,7 +1320,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
// Get 9-byte for total length
uint8_t const config_idx = CONFIG_NUM - 1;
- TU_LOG2("Get Configuration[0] Descriptor (9 bytes)\r\n");
+ TU_LOG_USBH("Get Configuration[0] Descriptor (9 bytes)\r\n");
TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, 9, process_enumeration, ENUM_GET_FULL_CONFIG_DESC), );
}
break;
@@ -1328,7 +1337,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
// Get full configuration descriptor
uint8_t const config_idx = CONFIG_NUM - 1;
- TU_LOG2("Get Configuration[0] Descriptor\r\n");
+ TU_LOG_USBH("Get Configuration[0] Descriptor\r\n");
TU_ASSERT( tuh_descriptor_get_configuration(daddr, config_idx, _usbh_ctrl_buf, total_len, process_enumeration, ENUM_SET_CONFIG), );
}
break;
@@ -1343,7 +1352,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
case ENUM_CONFIG_DRIVER:
{
- TU_LOG2("Device configured\r\n");
+ TU_LOG_USBH("Device configured\r\n");
usbh_device_t* dev = get_device(daddr);
TU_ASSERT(dev, );
@@ -1383,7 +1392,7 @@ static bool enum_new_device(hcd_event_t* event)
if ( !hcd_port_connect_status(_dev0.rhport) ) return true;
_dev0.speed = hcd_port_speed_get(_dev0.rhport );
- TU_LOG2("%s Speed\r\n", tu_str_speed[_dev0.speed]);
+ TU_LOG_USBH("%s Speed\r\n", tu_str_speed[_dev0.speed]);
// fake transfer to kick-off the enumeration process
tuh_xfer_t xfer;
@@ -1440,7 +1449,7 @@ static bool enum_request_set_addr(void)
uint8_t const new_addr = get_new_address(desc_device->bDeviceClass == TUSB_CLASS_HUB);
TU_ASSERT(new_addr != 0);
- TU_LOG2("Set Address = %d\r\n", new_addr);
+ TU_LOG_USBH("Set Address = %d\r\n", new_addr);
usbh_device_t* new_dev = get_device(new_addr);
@@ -1484,9 +1493,12 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur
{
usbh_device_t* dev = get_device(dev_addr);
- uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + tu_le16toh(desc_cfg->wTotalLength);
+ uint16_t const total_len = tu_le16toh(desc_cfg->wTotalLength);
+ uint8_t const* desc_end = ((uint8_t const*) desc_cfg) + total_len;
uint8_t const* p_desc = tu_desc_next(desc_cfg);
+ TU_LOG_USBH("Parsing Configuration descriptor (wTotalLength = %u)\r\n", total_len);
+
// parse each interfaces
while( p_desc < desc_end )
{
@@ -1524,15 +1536,14 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur
TU_ASSERT(drv_len >= sizeof(tusb_desc_interface_t));
// Find driver for this interface
- uint8_t drv_id;
- for (drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++)
+ for (uint8_t drv_id = 0; drv_id < USBH_CLASS_DRIVER_COUNT; drv_id++)
{
usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id];
if ( driver->open(dev->rhport, dev_addr, desc_itf, drv_len) )
{
// open successfully
- TU_LOG2(" %s opened\r\n", driver->name);
+ TU_LOG_USBH(" %s opened\r\n", driver->name);
// bind (associated) interfaces to found driver
for(uint8_t i=0; i<assoc_itf_count; i++)
@@ -1552,7 +1563,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur
if( drv_id >= USBH_CLASS_DRIVER_COUNT )
{
- TU_LOG(USBH_DBG_LVL, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n",
+ TU_LOG(USBH_DEBUG, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n",
desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol);
}
}
@@ -1571,12 +1582,13 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++)
{
// continue with next valid interface
- // TODO skip IAD binding interface such as CDCs
+ // 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)
{
usbh_class_driver_t const * driver = &usbh_class_drivers[drv_id];
- TU_LOG2("%s set config: itf = %u\r\n", driver->name, itf_num);
+ TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num);
driver->set_config(dev_addr, itf_num);
break;
}
@@ -1589,7 +1601,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
if (is_hub_addr(dev_addr))
{
- TU_LOG(USBH_DBG_LVL, "HUB address = %u is mounted\r\n", dev_addr);
+ TU_LOG(USBH_DEBUG, "HUB address = %u is mounted\r\n", dev_addr);
}else
{
// Invoke callback if available
diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h
index c156afea0..be9811641 100644
--- a/src/host/usbh_classdriver.h
+++ b/src/host/usbh_classdriver.h
@@ -29,11 +29,16 @@
#include "osal/osal.h"
#include "common/tusb_fifo.h"
+#include "common/tusb_private.h"
#ifdef __cplusplus
extern "C" {
#endif
+enum {
+ USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS)
+};
+
//--------------------------------------------------------------------+
// Class Driver API
//--------------------------------------------------------------------+