summaryrefslogtreecommitdiff
path: root/src/host
diff options
context:
space:
mode:
authorHa Thach <[email protected]>2024-03-25 19:15:39 +0700
committerGitHub <[email protected]>2024-03-25 19:15:39 +0700
commit5b0e255f7e5f49909be9d4a0bf0be302d26e598d (patch)
tree2e071c98d9e16efa833d2b600713288b6d694cae /src/host
parent0814ca0cc70f7343218c6637ce0b4deaf9058dc0 (diff)
parenta7a65e5d6d43fbb0c07eb82b3ab9fd8286dd3013 (diff)
Merge pull request #2530 from hathach/add-tuh-deinit
Diffstat (limited to 'src/host')
-rw-r--r--src/host/hcd.h3
-rw-r--r--src/host/hub.c8
-rw-r--r--src/host/hub.h13
-rw-r--r--src/host/usbh.c136
-rw-r--r--src/host/usbh.h4
-rw-r--r--src/host/usbh_pvt.h6
6 files changed, 113 insertions, 57 deletions
diff --git a/src/host/hcd.h b/src/host/hcd.h
index 2bde289df..d5804c608 100644
--- a/src/host/hcd.h
+++ b/src/host/hcd.h
@@ -130,6 +130,9 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) TU_AT
// Initialize controller to host mode
bool hcd_init(uint8_t rhport);
+// De-initialize controller
+bool hcd_deinit(uint8_t rhport);
+
// Interrupt Handler
void hcd_int_handler(uint8_t rhport, bool in_isr);
diff --git a/src/host/hub.c b/src/host/hub.c
index 3bac18698..e97014443 100644
--- a/src/host/hub.c
+++ b/src/host/hub.c
@@ -182,9 +182,13 @@ bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp,
//--------------------------------------------------------------------+
// CLASS-USBH API (don't require to verify parameters)
//--------------------------------------------------------------------+
-void hub_init(void)
-{
+bool hub_init(void) {
tu_memclr(hub_data, sizeof(hub_data));
+ return true;
+}
+
+bool hub_deinit(void) {
+ return true;
}
bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len)
diff --git a/src/host/hub.h b/src/host/hub.h
index 390740e1f..385efe6b2 100644
--- a/src/host/hub.h
+++ b/src/host/hub.h
@@ -187,16 +187,14 @@ bool hub_port_get_status (uint8_t hub_addr, uint8_t hub_port, void* resp,
bool hub_edpt_status_xfer(uint8_t dev_addr);
// Reset a port
-static inline bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port,
- tuh_xfer_cb_t complete_cb, uintptr_t user_data)
-{
+TU_ATTR_ALWAYS_INLINE static inline
+bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
return hub_port_set_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET, complete_cb, user_data);
}
// Clear Reset Change
-static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port,
- tuh_xfer_cb_t complete_cb, uintptr_t user_data)
-{
+TU_ATTR_ALWAYS_INLINE static inline
+bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data) {
return hub_port_clear_feature(hub_addr, hub_port, HUB_FEATURE_PORT_RESET_CHANGE, complete_cb, user_data);
}
@@ -204,7 +202,8 @@ static inline bool hub_port_clear_reset_change(uint8_t hub_addr, uint8_t hub_por
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
-void hub_init (void);
+bool hub_init (void);
+bool hub_deinit (void);
bool hub_open (uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len);
bool hub_set_config (uint8_t dev_addr, uint8_t itf_num);
bool hub_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 625857683..1edc43fd6 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -45,8 +45,13 @@
#endif
//--------------------------------------------------------------------+
-// Callback weak stubs (called if application does not provide)
+// Weak stubs: invoked if no strong implementation is available
//--------------------------------------------------------------------+
+TU_ATTR_WEAK bool hcd_deinit(uint8_t rhport) {
+ (void) rhport;
+ return false;
+}
+
TU_ATTR_WEAK void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) {
(void) rhport;
(void) eventid;
@@ -119,16 +124,17 @@ typedef struct {
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL
- #define DRIVER_NAME(_name) .name = _name,
+ #define DRIVER_NAME(_name) _name
#else
- #define DRIVER_NAME(_name)
+ #define DRIVER_NAME(_name) NULL
#endif
static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_CDC
{
- DRIVER_NAME("CDC")
+ .name = DRIVER_NAME("CDC"),
.init = cdch_init,
+ .deinit = cdch_deinit,
.open = cdch_open,
.set_config = cdch_set_config,
.xfer_cb = cdch_xfer_cb,
@@ -138,8 +144,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_MSC
{
- DRIVER_NAME("MSC")
+ .name = DRIVER_NAME("MSC"),
.init = msch_init,
+ .deinit = msch_deinit,
.open = msch_open,
.set_config = msch_set_config,
.xfer_cb = msch_xfer_cb,
@@ -149,8 +156,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_HID
{
- DRIVER_NAME("HID")
+ .name = DRIVER_NAME("HID"),
.init = hidh_init,
+ .deinit = hidh_deinit,
.open = hidh_open,
.set_config = hidh_set_config,
.xfer_cb = hidh_xfer_cb,
@@ -160,8 +168,9 @@ static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_HUB
{
- DRIVER_NAME("HUB")
+ .name = DRIVER_NAME("HUB"),
.init = hub_init,
+ .deinit = hub_deinit,
.open = hub_open,
.set_config = hub_set_config,
.xfer_cb = hub_xfer_cb,
@@ -171,9 +180,11 @@ static usbh_class_driver_t const usbh_class_drivers[] = {
#if CFG_TUH_VENDOR
{
- DRIVER_NAME("VENDOR")
+ .name = DRIVER_NAME("VENDOR"),
.init = cush_init,
- .open = cush_open_subtask,
+ .deinit = cush_deinit,
+ .open = cush_open,
+ .set_config = cush_set_config,
.xfer_cb = cush_isr,
.close = cush_close
}
@@ -338,55 +349,92 @@ bool tuh_inited(void) {
return _usbh_controller != TUSB_INDEX_INVALID_8;
}
-bool tuh_init(uint8_t controller_id) {
+bool tuh_init(uint8_t rhport) {
// skip if already initialized
- if ( tuh_inited() ) return true;
+ if (tuh_rhport_is_active(rhport)) return true;
- TU_LOG_USBH("USBH init on controller %u\r\n", controller_id);
- TU_LOG_INT_USBH(sizeof(usbh_device_t));
- TU_LOG_INT_USBH(sizeof(hcd_event_t));
- TU_LOG_INT_USBH(sizeof(_ctrl_xfer));
- TU_LOG_INT_USBH(sizeof(tuh_xfer_t));
- TU_LOG_INT_USBH(sizeof(tu_fifo_t));
- TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t));
+ TU_LOG_USBH("USBH init on controller %u\r\n", rhport);
- // Event queue
- _usbh_q = osal_queue_create( &_usbh_qdef );
- TU_ASSERT(_usbh_q != NULL);
+ // Init host stack if not already
+ if (!tuh_inited()) {
+ TU_LOG_INT_USBH(sizeof(usbh_device_t));
+ TU_LOG_INT_USBH(sizeof(hcd_event_t));
+ TU_LOG_INT_USBH(sizeof(_ctrl_xfer));
+ TU_LOG_INT_USBH(sizeof(tuh_xfer_t));
+ TU_LOG_INT_USBH(sizeof(tu_fifo_t));
+ TU_LOG_INT_USBH(sizeof(tu_edpt_stream_t));
+
+ // Event queue
+ _usbh_q = osal_queue_create(&_usbh_qdef);
+ TU_ASSERT(_usbh_q != NULL);
#if OSAL_MUTEX_REQUIRED
- // Init mutex
- _usbh_mutex = osal_mutex_create(&_usbh_mutexdef);
- TU_ASSERT(_usbh_mutex);
+ // Init mutex
+ _usbh_mutex = osal_mutex_create(&_usbh_mutexdef);
+ TU_ASSERT(_usbh_mutex);
#endif
- // Get application driver if available
- if ( usbh_app_driver_get_cb ) {
- _app_driver = usbh_app_driver_get_cb(&_app_driver_count);
- }
+ // Get application driver if available
+ if (usbh_app_driver_get_cb) {
+ _app_driver = usbh_app_driver_get_cb(&_app_driver_count);
+ }
- // Device
- tu_memclr(&_dev0, sizeof(_dev0));
- tu_memclr(_usbh_devices, sizeof(_usbh_devices));
- tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer));
+ // Device
+ tu_memclr(&_dev0, sizeof(_dev0));
+ tu_memclr(_usbh_devices, sizeof(_usbh_devices));
+ tu_memclr(&_ctrl_xfer, sizeof(_ctrl_xfer));
- for(uint8_t i=0; i<TOTAL_DEVICES; i++) {
- clear_device(&_usbh_devices[i]);
- }
+ for (uint8_t i = 0; i < TOTAL_DEVICES; i++) {
+ clear_device(&_usbh_devices[i]);
+ }
- // Class drivers
- for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
- usbh_class_driver_t const* driver = get_driver(drv_id);
- if (driver) {
- TU_LOG_USBH("%s init\r\n", driver->name);
- driver->init();
+ // Class drivers
+ for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
+ usbh_class_driver_t const* driver = get_driver(drv_id);
+ if (driver) {
+ TU_LOG_USBH("%s init\r\n", driver->name);
+ driver->init();
+ }
}
}
- _usbh_controller = controller_id;;
+ // Init host controller
+ _usbh_controller = rhport;;
+ TU_ASSERT(hcd_init(rhport));
+ hcd_int_enable(rhport);
+
+ return true;
+}
+
+bool tuh_deinit(uint8_t rhport) {
+ if (!tuh_rhport_is_active(rhport)) return true;
+
+ // deinit host controller
+ hcd_int_disable(rhport);
+ hcd_deinit(rhport);
+
+ _usbh_controller = TUSB_INDEX_INVALID_8;
+
+ // deinit host stack if no controller is active
+ if (!tuh_inited()) {
+ // Class drivers
+ for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) {
+ usbh_class_driver_t const* driver = get_driver(drv_id);
+ if (driver) {
+ TU_LOG_USBH("%s deinit\r\n", driver->name);
+ driver->deinit();
+ }
+ }
- TU_ASSERT(hcd_init(controller_id));
- hcd_int_enable(controller_id);
+ osal_queue_delete(_usbh_q);
+ _usbh_q = NULL;
+
+ #if OSAL_MUTEX_REQUIRED
+ // TODO make sure there is no task waiting on this mutex
+ osal_mutex_delete(_usbh_mutex);
+ _usbh_mutex = NULL;
+ #endif
+ }
return true;
}
diff --git a/src/host/usbh.h b/src/host/usbh.h
index 9ff118543..0e31e80a7 100644
--- a/src/host/usbh.h
+++ b/src/host/usbh.h
@@ -109,7 +109,11 @@ bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param);
// Init host stack
bool tuh_init(uint8_t rhport);
+// Deinit host stack on rhport
+bool tuh_deinit(uint8_t rhport);
+
// Check if host stack is already initialized with any roothub ports
+// To check if an rhport is initialized, use tuh_rhport_is_active()
bool tuh_inited(void);
// Task function should be called in main/rtos loop, extended version of tuh_task()
diff --git a/src/host/usbh_pvt.h b/src/host/usbh_pvt.h
index 4ed2a72b5..95de915e9 100644
--- a/src/host/usbh_pvt.h
+++ b/src/host/usbh_pvt.h
@@ -50,11 +50,9 @@ enum {
//--------------------------------------------------------------------+
typedef struct {
- #if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL
char const* name;
- #endif
-
- void (* const init )(void);
+ bool (* const init )(void);
+ bool (* const deinit )(void);
bool (* const open )(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
bool (* const set_config )(uint8_t dev_addr, uint8_t itf_num);
bool (* const xfer_cb )(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);