summaryrefslogtreecommitdiff
path: root/src/host
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2023-10-17 22:31:33 +0700
committerGitHub <[email protected]>2023-10-17 22:31:33 +0700
commit80ee30724479e6c756b7e10900f105e81217e1c0 (patch)
treea8d13578e653c43df0288e294d05bdcb8658a254 /src/host
parentc4566c4d2ba5219e6c2ea821912b888d0270ff07 (diff)
parent118823c254ab002cf3aeed54653de0c9a93672d3 (diff)
Merge branch 'master' into feat-stm32u575_nucleo
Diffstat (limited to 'src/host')
-rw-r--r--src/host/hcd.h22
-rw-r--r--src/host/usbh.c89
-rw-r--r--src/host/usbh.h11
-rw-r--r--src/host/usbh_pvt.h10
4 files changed, 59 insertions, 73 deletions
diff --git a/src/host/hcd.h b/src/host/hcd.h
index 9bcc1c6df..2bde289df 100644
--- a/src/host/hcd.h
+++ b/src/host/hcd.h
@@ -39,7 +39,7 @@
// Configuration
//--------------------------------------------------------------------+
-// Max number of endpoints per device
+// Max number of endpoints pair per device
// TODO optimize memory usage
#ifndef CFG_TUH_ENDPOINT_MAX
#define CFG_TUH_ENDPOINT_MAX 16
@@ -131,7 +131,7 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_AT
bool hcd_init(uint8_t rhport);
// Interrupt Handler
-void hcd_int_handler(uint8_t rhport);
+void hcd_int_handler(uint8_t rhport, bool in_isr);
// Enable USB interrupt
void hcd_int_enable (uint8_t rhport);
@@ -167,17 +167,17 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr);
//--------------------------------------------------------------------+
// Open an endpoint
-bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
+bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * ep_desc);
// Submit a transfer, when complete hcd_event_xfer_complete() must be invoked
-bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen);
+bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen);
// Abort a queued transfer. Note: it can only abort transfer that has not been started
// Return true if a queued transfer is aborted, false if there is no transfer to abort
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr);
// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked
-bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
+bool hcd_setup_send(uint8_t rhport, uint8_t daddr, uint8_t const setup_packet[8]);
// clear stall, data toggle is also reset to DATA0
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr);
@@ -198,8 +198,7 @@ extern void hcd_event_handler(hcd_event_t const* event, bool in_isr);
// Helper to send device attach event
TU_ATTR_ALWAYS_INLINE static inline
-void hcd_event_device_attach(uint8_t rhport, bool in_isr)
-{
+void hcd_event_device_attach(uint8_t rhport, bool in_isr) {
hcd_event_t event;
event.rhport = rhport;
event.event_id = HCD_EVENT_DEVICE_ATTACH;
@@ -211,8 +210,7 @@ void hcd_event_device_attach(uint8_t rhport, bool in_isr)
// Helper to send device removal event
TU_ATTR_ALWAYS_INLINE static inline
-void hcd_event_device_remove(uint8_t rhport, bool in_isr)
-{
+void hcd_event_device_remove(uint8_t rhport, bool in_isr) {
hcd_event_t event;
event.rhport = rhport;
event.event_id = HCD_EVENT_DEVICE_REMOVE;
@@ -224,10 +222,8 @@ void hcd_event_device_remove(uint8_t rhport, bool in_isr)
// Helper to send USB transfer event
TU_ATTR_ALWAYS_INLINE static inline
-void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr)
-{
- hcd_event_t event =
- {
+void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr) {
+ hcd_event_t event = {
.rhport = 0, // TODO correct rhport
.event_id = HCD_EVENT_XFER_COMPLETE,
.dev_addr = dev_addr,
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 5423df669..8d75c9726 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -552,8 +552,7 @@ static void _control_blocking_complete_cb(tuh_xfer_t* xfer)
}
// TODO timeout_ms is not supported yet
-bool tuh_control_xfer (tuh_xfer_t* xfer)
-{
+bool tuh_control_xfer (tuh_xfer_t* xfer) {
// EP0 with setup packet
TU_VERIFY(xfer->ep_addr == 0 && xfer->setup);
@@ -565,8 +564,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
(void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE);
- if (is_idle)
- {
+ if (is_idle) {
_ctrl_xfer.stage = CONTROL_STAGE_SETUP;
_ctrl_xfer.daddr = daddr;
_ctrl_xfer.actual_len = 0;
@@ -585,14 +583,12 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
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(CFG_TUH_LOG_LEVEL, xfer->setup);
+ TU_LOG_BUF(CFG_TUH_LOG_LEVEL, xfer->setup, 8);
TU_LOG_USBH("\r\n");
- if (xfer->complete_cb)
- {
+ if (xfer->complete_cb) {
TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) );
- }else
- {
+ }else {
// blocking if complete callback is not provided
// change callback to internal blocking, and result as user argument
volatile xfer_result_t result = XFER_RESULT_INVALID;
@@ -656,30 +652,23 @@ static void _xfer_complete(uint8_t daddr, xfer_result_t result)
}
}
-static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
-{
+static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
(void) ep_addr;
const uint8_t rhport = usbh_get_rhport(dev_addr);
tusb_control_request_t const * request = &_ctrl_xfer.request;
- if (XFER_RESULT_SUCCESS != result)
- {
+ if (XFER_RESULT_SUCCESS != result) {
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_BUF(request, 8);
TU_LOG1("\r\n");
- #endif
// terminate transfer if any stage failed
_xfer_complete(dev_addr, result);
- }else
- {
- switch(_ctrl_xfer.stage)
- {
+ }else {
+ switch(_ctrl_xfer.stage) {
case CONTROL_STAGE_SETUP:
- if (request->wLength)
- {
+ if (request->wLength) {
// DATA stage: initial data toggle is always 1
_set_control_xfer_stage(CONTROL_STAGE_DATA);
TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) );
@@ -688,8 +677,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
TU_ATTR_FALLTHROUGH;
case CONTROL_STAGE_DATA:
- if (request->wLength)
- {
+ if (request->wLength) {
TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr);
TU_LOG_MEM(CFG_TUH_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2);
}
@@ -765,29 +753,33 @@ bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) {
// USBH API For Class Driver
//--------------------------------------------------------------------+
-uint8_t usbh_get_rhport(uint8_t dev_addr)
-{
- usbh_device_t* dev = get_device(dev_addr);
+uint8_t usbh_get_rhport(uint8_t dev_addr) {
+ usbh_device_t *dev = get_device(dev_addr);
return dev ? dev->rhport : _dev0.rhport;
}
-uint8_t* usbh_get_enum_buf(void)
-{
+uint8_t *usbh_get_enum_buf(void) {
return _usbh_ctrl_buf;
}
-void usbh_int_set(bool enabled)
-{
+void usbh_int_set(bool enabled) {
// TODO all host controller if multiple are used since they shared the same event queue
- if (enabled)
- {
+ if (enabled) {
hcd_int_enable(_usbh_controller);
- }else
- {
+ } else {
hcd_int_disable(_usbh_controller);
}
}
+void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr) {
+ hcd_event_t event = { 0 };
+ event.event_id = USBH_EVENT_FUNC_CALL;
+ event.func_call.func = func;
+ event.func_call.param = param;
+
+ osal_queue_send(_usbh_q, &event, in_isr);
+}
+
//--------------------------------------------------------------------+
// Endpoint API
//--------------------------------------------------------------------+
@@ -825,6 +817,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr)
}
// Submit an transfer
+// TODO call usbh_edpt_release if failed
bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes,
tuh_xfer_cb_t complete_cb, uintptr_t user_data)
{
@@ -862,7 +855,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b
ep_state->busy = 0;
ep_state->claimed = 0;
TU_LOG1("Failed\r\n");
- TU_BREAKPOINT();
+// TU_BREAKPOINT();
return false;
}
}
@@ -929,6 +922,7 @@ TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr)
switch (event->event_id)
{
// case HCD_EVENT_DEVICE_REMOVE:
+// // FIXME device remove from a hub need an HCD API for hcd to free up endpoint
// // mark device as removing to prevent further xfer before the event is processed in usbh task
// break;
@@ -1538,9 +1532,7 @@ static bool enum_new_device(hcd_event_t* event)
xfer.result = XFER_RESULT_SUCCESS;
xfer.user_data = ENUM_ADDR0_DEVICE_DESC;
-
process_enumeration(&xfer);
-
}
#if CFG_TUH_HUB
else
@@ -1722,19 +1714,16 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur
return true;
}
-void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
-{
+void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num) {
usbh_device_t* dev = get_device(dev_addr);
- for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++)
- {
+ for(itf_num++; itf_num < CFG_TUH_INTERFACE_MAX; itf_num++) {
// continue with next valid interface
// 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];
usbh_class_driver_t const * driver = get_driver(drv_id);
- if (driver)
- {
+ if (driver) {
TU_LOG_USBH("%s set config: itf = %u\r\n", driver->name, itf_num);
driver->set_config(dev_addr, itf_num);
break;
@@ -1742,23 +1731,19 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
}
// all interface are configured
- if (itf_num == CFG_TUH_INTERFACE_MAX)
- {
+ if (itf_num == CFG_TUH_INTERFACE_MAX) {
enum_full_complete();
- if (is_hub_addr(dev_addr))
- {
+ if (is_hub_addr(dev_addr)) {
TU_LOG(CFG_TUH_LOG_LEVEL, "HUB address = %u is mounted\r\n", dev_addr);
- }else
- {
+ }else {
// Invoke callback if available
if (tuh_mount_cb) tuh_mount_cb(dev_addr);
}
}
}
-static void enum_full_complete(void)
-{
+static void enum_full_complete(void) {
// mark enumeration as complete
_dev0.enumerating = 0;
diff --git a/src/host/usbh.h b/src/host/usbh.h
index 684e8240e..770d70dfe 100644
--- a/src/host/usbh.h
+++ b/src/host/usbh.h
@@ -124,11 +124,16 @@ void tuh_task(void) {
bool tuh_task_event_ready(void);
#ifndef _TUSB_HCD_H_
-extern void hcd_int_handler(uint8_t rhport);
+extern void hcd_int_handler(uint8_t rhport, bool in_isr);
#endif
-// Interrupt handler, name alias to HCD
-#define tuh_int_handler hcd_int_handler
+// Interrupt handler alias to HCD with in_isr as optional parameter
+// - tuh_int_handler(rhport) --> hcd_int_handler(rhport, true)
+// - tuh_int_handler(rhport, in_isr) --> hcd_int_handler(rhport, in_isr)
+// Note: this is similar to TU_VERIFY(), _GET_3RD_ARG() is defined in tusb_verify.h
+#define _tuh_int_handler_1arg(_rhport) hcd_int_handler(_rhport, true)
+#define _tuh_int_hanlder_2arg(_rhport, _in_isr) hcd_int_handler(_rhport, _in_isr)
+#define tuh_int_handler(...) _GET_3RD_ARG(__VA_ARGS__, _tuh_int_hanlder_2arg, _tuh_int_handler_1arg, _dummy)(__VA_ARGS__)
// Check if roothub port is initialized and active as a host
bool tuh_rhport_is_active(uint8_t rhport);
diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h
index 0b58a91bc..2b61a77db 100644
--- a/src/host/usbh_pvt.h
+++ b/src/host/usbh_pvt.h
@@ -24,8 +24,8 @@
* This file is part of the TinyUSB stack.
*/
-#ifndef _TUSB_USBH_CLASSDRIVER_H_
-#define _TUSB_USBH_CLASSDRIVER_H_
+#ifndef _TUSB_USBH_PVT_H_
+#define _TUSB_USBH_PVT_H_
#include "osal/osal.h"
#include "common/tusb_fifo.h"
@@ -76,6 +76,8 @@ uint8_t* usbh_get_enum_buf(void);
void usbh_int_set(bool enabled);
+void usbh_defer_func(osal_task_func_t func, void *param, bool in_isr);
+
//--------------------------------------------------------------------+
// USBH Endpoint API
//--------------------------------------------------------------------+
@@ -85,12 +87,10 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b
tuh_xfer_cb_t complete_cb, uintptr_t user_data);
TU_ATTR_ALWAYS_INLINE
-static inline bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
-{
+static inline bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) {
return usbh_edpt_xfer_with_callback(dev_addr, ep_addr, buffer, total_bytes, NULL, 0);
}
-
// Claim an endpoint before submitting a transfer.
// If caller does not make any transfer, it must release endpoint for others.
bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr);