diff options
| author | Ha Thach <[email protected]> | 2024-03-25 19:15:39 +0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-03-25 19:15:39 +0700 |
| commit | 5b0e255f7e5f49909be9d4a0bf0be302d26e598d (patch) | |
| tree | 2e071c98d9e16efa833d2b600713288b6d694cae /src/host | |
| parent | 0814ca0cc70f7343218c6637ce0b4deaf9058dc0 (diff) | |
| parent | a7a65e5d6d43fbb0c07eb82b3ab9fd8286dd3013 (diff) | |
Merge pull request #2530 from hathach/add-tuh-deinit
Diffstat (limited to 'src/host')
| -rw-r--r-- | src/host/hcd.h | 3 | ||||
| -rw-r--r-- | src/host/hub.c | 8 | ||||
| -rw-r--r-- | src/host/hub.h | 13 | ||||
| -rw-r--r-- | src/host/usbh.c | 136 | ||||
| -rw-r--r-- | src/host/usbh.h | 4 | ||||
| -rw-r--r-- | src/host/usbh_pvt.h | 6 |
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); |
