diff --git a/src/host/ehci/ehci.c b/src/host/ehci/ehci.c index fa4a1f3f3..e4dedd0d0 100644 --- a/src/host/ehci/ehci.c +++ b/src/host/ehci/ehci.c @@ -133,7 +133,7 @@ tusb_speed_t hcd_port_speed_get(uint8_t hostid) } // TODO refractor abtract later -void hcd_port_unplug(uint8_t hostid) +void hcd_device_remove(uint8_t rhport, uint8_t dev_addr) { ehci_data.regs->usb_cmd_bit.advance_async = 1; // Async doorbell check EHCI 4.8.2 for operational details } @@ -153,9 +153,7 @@ static bool ehci_init(uint8_t hostid) regs->usb_sts = EHCI_INT_MASK_ALL; // 2. clear all status regs->usb_int_enable = EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE | -#if EHCI_PERIODIC_LIST EHCI_INT_MASK_NXP_PERIODIC | -#endif EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_ASYNC; //------------- Asynchronous List -------------// @@ -170,7 +168,6 @@ static bool ehci_init(uint8_t hostid) regs->async_list_base = (uint32_t) async_head; -#if EHCI_PERIODIC_LIST //------------- Periodic List -------------// // Build the polling interval tree with 1 ms, 2 ms, 4 ms and 8 ms (framesize) only @@ -209,19 +206,13 @@ static bool ehci_init(uint8_t hostid) period_1ms->terminate = 1; regs->periodic_list_base = (uint32_t) framelist; -#else - regs->periodic_list_base = 0; -#endif //------------- TT Control (NXP only) -------------// regs->tt_control = 0; //------------- USB CMD Register -------------// - regs->usb_cmd |= BIT_(EHCI_USBCMD_POS_RUN_STOP) | BIT_(EHCI_USBCMD_POS_ASYNC_ENABLE) -#if EHCI_PERIODIC_LIST | BIT_(EHCI_USBCMD_POS_PERIOD_ENABLE) // TODO enable period list only there is int/iso endpoint -#endif | ((EHCI_CFG_FRAMELIST_SIZE_BITS & BIN8(011)) << EHCI_USBCMD_POS_FRAMELIST_SZIE) | ((EHCI_CFG_FRAMELIST_SIZE_BITS >> 2) << EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB); @@ -411,11 +402,9 @@ bool hcd_pipe_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const list_head = (ehci_link_t*) get_async_head(_usbh_devices[dev_addr].rhport); break; - #if EHCI_PERIODIC_LIST // TODO refractor/group this together case TUSB_XFER_INTERRUPT: list_head = get_period_head(_usbh_devices[dev_addr].rhport, p_qhd->interval_ms); break; - #endif case TUSB_XFER_ISOCHRONOUS: // TODO iso is not supported @@ -479,14 +468,12 @@ bool hcd_pipe_close(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) (ehci_link_t*) get_async_head( _usbh_devices[dev_addr].rhport ), (ehci_link_t*) p_qhd), false ); } - #if EHCI_PERIODIC_LIST // TODO refractor/group this together else { TU_ASSERT_ERR( list_remove_qhd( get_period_head( _usbh_devices[dev_addr].rhport, p_qhd->interval_ms ), (ehci_link_t*) p_qhd), false ); } - #endif return true; } @@ -610,7 +597,6 @@ static void async_list_xfer_complete_isr(ehci_qhd_t * const async_head) // TODO abstract max loop guard for async } -#if EHCI_PERIODIC_LIST // TODO refractor/group this together static void period_list_xfer_complete_isr(uint8_t hostid, uint8_t interval_ms) { uint8_t max_loop = 0; @@ -645,7 +631,6 @@ static void period_list_xfer_complete_isr(uint8_t hostid, uint8_t interval_ms) max_loop++; } } -#endif static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd) { @@ -699,7 +684,6 @@ static void xfer_error_isr(uint8_t hostid) max_loop++; }while(p_qhd != async_head && max_loop < HCD_MAX_ENDPOINT*CFG_TUSB_HOST_DEVICE_MAX); // async list traversal, stop if loop around - #if EHCI_PERIODIC_LIST //------------- TODO refractor period list -------------// uint32_t const period_1ms_addr = (uint32_t) get_period_head(hostid, 1); for (uint8_t interval_ms=1; interval_ms <= EHCI_FRAMELIST_SIZE; interval_ms *= 2) @@ -732,7 +716,6 @@ static void xfer_error_isr(uint8_t hostid) period_max_loop++; } } - #endif } //------------- Host Controller Driver's Interrupt Handler -------------// @@ -770,7 +753,6 @@ void hal_hcd_isr(uint8_t hostid) async_list_xfer_complete_isr( get_async_head(hostid) ); } -#if EHCI_PERIODIC_LIST // TODO refractor/group this together if (int_status & EHCI_INT_MASK_NXP_PERIODIC) { for (uint8_t i=1; i <= EHCI_FRAMELIST_SIZE; i *= 2) @@ -778,7 +760,6 @@ void hal_hcd_isr(uint8_t hostid) period_list_xfer_complete_isr( hostid, i ); } } -#endif //------------- There is some removed async previously -------------// if (int_status & EHCI_INT_MASK_ASYNC_ADVANCE) // need to place after EHCI_INT_MASK_NXP_ASYNC @@ -801,12 +782,10 @@ static inline ehci_qhd_t* get_async_head(uint8_t hostid) return get_control_qhd(0); } -#if EHCI_PERIODIC_LIST // TODO refractor/group this together static inline ehci_link_t* get_period_head(uint8_t hostid, uint8_t interval_ms) { return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min8(EHCI_FRAMELIST_SIZE, interval_ms) ) ]; } -#endif static inline ehci_qhd_t* get_control_qhd(uint8_t dev_addr) { diff --git a/src/host/ehci/ehci.h b/src/host/ehci/ehci.h index 3758dc223..f1fe75cf1 100644 --- a/src/host/ehci/ehci.h +++ b/src/host/ehci/ehci.h @@ -68,9 +68,6 @@ //--------------------------------------------------------------------+ // EHCI CONFIGURATION & CONSTANTS //--------------------------------------------------------------------+ -#define HOST_HCD_XFER_INTERRUPT // TODO interrupt is used widely, should always be enalbed -#define EHCI_PERIODIC_LIST (defined HOST_HCD_XFER_INTERRUPT || defined HOST_HCD_XFER_ISOCHRONOUS) - #define EHCI_CFG_FRAMELIST_SIZE_BITS 7 /// Framelist Size (NXP specific) (0:1024) - (1:512) - (2:256) - (3:128) - (4:64) - (5:32) - (6:16) - (7:8) #define EHCI_FRAMELIST_SIZE (1024 >> EHCI_CFG_FRAMELIST_SIZE_BITS) diff --git a/src/host/hcd.h b/src/host/hcd.h index 5a7f0756b..dcc2bdf53 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -96,12 +96,21 @@ enum { #endif //--------------------------------------------------------------------+ -// USBH-HCD API +// HCD API //--------------------------------------------------------------------+ bool hcd_init(void); void hcd_int_enable (uint8_t rhport); void hcd_int_disable(uint8_t rhport); +// PORT API +/// return the current connect status of roothub port +bool hcd_port_connect_status(uint8_t hostid) ATTR_PURE ATTR_WARN_UNUSED_RESULT; // TODO make inline if possible +void hcd_port_reset(uint8_t hostid); +tusb_speed_t hcd_port_speed_get(uint8_t hostid) ATTR_PURE ATTR_WARN_UNUSED_RESULT; // TODO make inline if possible + +// Call by USBH after event device remove +void hcd_device_remove(uint8_t rhport, uint8_t dev_addr); + //--------------------------------------------------------------------+ // Event function //--------------------------------------------------------------------+ @@ -111,7 +120,7 @@ void hcd_event_handler(hcd_event_t const* event, bool in_isr); void hcd_event_device_attach(uint8_t rhport); // Helper to send device removal event -void hcd_event_device_remove(uint8_t hostid); +void hcd_event_device_remove(uint8_t rhport); // Helper to send USB transfer event void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes); @@ -140,15 +149,6 @@ bool hcd_pipe_clear_stall(uint8_t dev_addr, uint8_t ep_addr); tusb_error_t hcd_pipe_cancel()ATTR_WARN_UNUSED_RESULT; #endif -//--------------------------------------------------------------------+ -// PORT API -//--------------------------------------------------------------------+ -/// return the current connect status of roothub port -bool hcd_port_connect_status(uint8_t hostid) ATTR_PURE ATTR_WARN_UNUSED_RESULT; // TODO make inline if possible -void hcd_port_reset(uint8_t hostid); -tusb_speed_t hcd_port_speed_get(uint8_t hostid) ATTR_PURE ATTR_WARN_UNUSED_RESULT; // TODO make inline if possible -void hcd_port_unplug(uint8_t hostid); // called by usbh to instruct hcd that it can execute unplug procedure - #ifdef __cplusplus } #endif diff --git a/src/host/usbh.c b/src/host/usbh.c index 8e03d97d1..3ab3bd71e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -319,15 +319,16 @@ void hcd_event_device_remove(uint8_t hostid) // a device unplugged on hostid, hub_addr, hub_port // return true if found and unmounted device, false if cannot find -static void usbh_device_unplugged(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port) +static void usbh_device_unplugged(uint8_t rhport, uint8_t hub_addr, uint8_t hub_port) { bool is_found = false; + //------------- find the all devices (star-network) under port that is unplugged -------------// for (uint8_t dev_addr = 0; dev_addr <= CFG_TUSB_HOST_DEVICE_MAX; dev_addr ++) { usbh_device_t* dev = &_usbh_devices[dev_addr]; - if (dev->rhport == hostid && + if (dev->rhport == rhport && (hub_addr == 0 || dev->hub_addr == hub_addr) && // hub_addr == 0 & hub_port == 0 means roothub (hub_port == 0 || dev->hub_port == hub_port) && dev->state != TUSB_DEVICE_STATE_UNPLUG) @@ -349,11 +350,14 @@ static void usbh_device_unplugged(uint8_t hostid, uint8_t hub_addr, uint8_t hub_ usbh_pipe_control_close(dev_addr); +// hcd_device_remove(rhport, dev_addr); + is_found = true; } } - if (is_found) hcd_port_unplug(_usbh_devices[0].rhport); // TODO hack + // FIXME remove + if (is_found) hcd_device_remove(_usbh_devices[0].rhport, 0); } diff --git a/src/tusb_option.h b/src/tusb_option.h index e8baf4149..8b2e59b17 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -212,9 +212,6 @@ //------------- HID CLASS -------------// #define HOST_CLASS_HID ( CFG_TUH_HID_KEYBOARD + CFG_TUH_HID_MOUSE + CFG_TUSB_HOST_HID_GENERIC ) -// #if HOST_CLASS_HID -// #define HOST_HCD_XFER_INTERRUPT -// #endif #ifndef CFG_TUSB_HOST_ENUM_BUFFER_SIZE #define CFG_TUSB_HOST_ENUM_BUFFER_SIZE 256 diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_ehci_init.c b/tests/lpc18xx_43xx/test/host/ehci/test_ehci_init.c index c61becd69..8d552cb8a 100644 --- a/tests/lpc18xx_43xx/test/host/ehci/test_ehci_init.c +++ b/tests/lpc18xx_43xx/test/host/ehci/test_ehci_init.c @@ -125,7 +125,6 @@ void check_qhd_endpoint_link(ehci_link_t *p_prev, ehci_qhd_t *p_qhd) void test_hcd_init_period_list(void) { -#if EHCI_PERIODIC_LIST ehci_registers_t* const regs = get_operational_register(hostid); ehci_qhd_t * const period_head_arr = get_period_head(hostid, 1); ehci_link_t * const framelist = get_period_frame_list(hostid); @@ -153,7 +152,6 @@ void test_hcd_init_period_list(void) } TEST_ASSERT_TRUE(period_head_arr[0].next.terminate); -#endif } void test_hcd_init_tt_control(void) @@ -166,12 +164,7 @@ void test_hcd_init_usbcmd(void) ehci_registers_t* const regs = get_operational_register(hostid); TEST_ASSERT(regs->usb_cmd_bit.async_enable); - -#if EHCI_PERIODIC_LIST TEST_ASSERT(regs->usb_cmd_bit.periodic_enable); -#else - TEST_ASSERT_FALSE(regs->usb_cmd_bit.periodic_enable); -#endif //------------- Framelist size (NXP specific) -------------// TEST_ASSERT_BITS(BIN8(11), EHCI_CFG_FRAMELIST_SIZE_BITS, regs->usb_cmd_bit.framelist_size);