diff --git a/tests/test/support/ehci_controller.c b/tests/test/support/ehci_controller.c index fed3c730..0bc09f53 100644 --- a/tests/test/support/ehci_controller.c +++ b/tests/test/support/ehci_controller.c @@ -76,3 +76,13 @@ void ehci_controller_run(uint8_t hostid) regs->usb_sts = EHCI_INT_MASK_NXP_ASYNC; } + +void ehci_controller_device_plug(uint8_t hostid, tusb_speed_t speed) +{ + ehci_registers_t* const regs = get_operational_register(hostid); + + regs->usb_sts_bit.port_change_detect = 1; + regs->portsc_bit.connect_status_change = 1; + regs->portsc_bit.current_connect_status = 1; + regs->portsc_bit.nxp_port_speed = speed; +} diff --git a/tests/test/support/ehci_controller.h b/tests/test/support/ehci_controller.h index 945e8e13..aee3f011 100644 --- a/tests/test/support/ehci_controller.h +++ b/tests/test/support/ehci_controller.h @@ -56,6 +56,7 @@ #endif void ehci_controller_run(uint8_t hostid); +void ehci_controller_device_plug(uint8_t hostid, tusb_speed_t speed); #ifdef __cplusplus } diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c index 2fefed23..6caf1e71 100644 --- a/tinyusb/host/ehci/ehci.c +++ b/tinyusb/host/ehci/ehci.c @@ -134,6 +134,32 @@ tusb_error_t hcd_init(void) return TUSB_ERROR_NONE; } +//--------------------------------------------------------------------+ +// PORT API +//--------------------------------------------------------------------+ +void hcd_port_reset(uint8_t hostid) +{ + ehci_registers_t* const regs = get_operational_register(hostid); + + regs->portsc_bit.port_enable = 0; // disable port before reset + regs->portsc_bit.port_reset = 1; + +#ifndef _TEST_ + // NXP specific, port reset will automatically be 0 when reset sequence complete + while( regs->portsc_bit.port_reset || !regs->portsc_bit.port_enable){} +#endif +} + +bool hcd_port_connect_status(uint8_t hostid) +{ + return false; +} + +tusb_speed_t hcd_port_speed(uint8_t hostid) +{ + return TUSB_SPEED_HIGH; +} + //--------------------------------------------------------------------+ // EHCI Interrupt Handler //--------------------------------------------------------------------+ @@ -143,6 +169,22 @@ static inline uint8_t get_qhd_index(ehci_qhd_t * p_qhd) return p_qhd - ehci_data.device[p_qhd->device_address].qhd; } + +void port_connect_status_isr(uint8_t hostid) +{ + ehci_registers_t* const regs = get_operational_register(hostid); + + if (regs->portsc_bit.current_connect_status) // device plugged + { + hcd_port_reset(hostid); + usbh_device_plugged_isr(hostid, regs->portsc_bit.nxp_port_speed); // NXP specific port speed + }else // device unplugged + { +// usbh_device_ + } + +} + void async_list_process_isr(ehci_qhd_t * const async_head, ehci_registers_t * const regs) { ehci_qhd_t *p_qhd = async_head; @@ -183,7 +225,6 @@ void async_list_process_isr(ehci_qhd_t * const async_head, ehci_registers_t * co } //------------- Host Controller Driver's Interrupt Handler -------------// -// TODO this isr is not properly go through TDD void hcd_isr(uint8_t hostid) { ehci_registers_t* const regs = get_operational_register(hostid); @@ -211,7 +252,14 @@ void hcd_isr(uint8_t hostid) if (int_status & EHCI_INT_MASK_PORT_CHANGE) { -// port_status_change_isr(h) + printf("%s %d\n", __PRETTY_FUNCTION__, __LINE__); + if (regs->portsc_bit.connect_status_change) + { + printf("%s %d\n", __PRETTY_FUNCTION__, __LINE__); + port_connect_status_isr(hostid); + } + + regs->portsc |= EHCI_PORTSC_MASK_ALL; // Acknowledge all the change bit in portsc } if (int_status & EHCI_INT_MASK_ASYNC_ADVANCE) @@ -323,19 +371,6 @@ tusb_error_t hcd_controller_reset(uint8_t hostid) return timeout_expired(&timeout) ? TUSB_ERROR_OSAL_TIMEOUT : TUSB_ERROR_NONE; } -//--------------------------------------------------------------------+ -// PORT API -//--------------------------------------------------------------------+ -bool hcd_port_connect_status(uint8_t core_id) -{ - return false; -} - -tusb_speed_t hcd_port_speed(uint8_t core_id) -{ - return TUSB_SPEED_HIGH; -} - //--------------------------------------------------------------------+ // PIPE API //--------------------------------------------------------------------+ diff --git a/tinyusb/host/ehci/ehci.h b/tinyusb/host/ehci/ehci.h index cd03c2b9..bceb78e7 100644 --- a/tinyusb/host/ehci/ehci.h +++ b/tinyusb/host/ehci/ehci.h @@ -327,6 +327,17 @@ enum ehci_usbcmd_pos_ { EHCI_USBCMD_POS_INTERRUPT_THRESHOLD = 16 }; +enum ehci_portsc_change_mask_{ + EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE = BIT_(1), + EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE = BIT_(3), + EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE = BIT_(5), + + EHCI_PORTSC_MASK_ALL = + EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE | + EHCI_PORTSC_MASK_PORT_ENABLE_CHAGNE | + EHCI_PORTSC_MASK_OVER_CURRENT_CHANGE +}; + typedef volatile struct { union { uint32_t usb_cmd ; ///< The Command Register indicates the command to be executed by the serial bus host controller. Writing to the register causes a command to be executed diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c index f0b79dab..05234aad 100644 --- a/tinyusb/host/usbh.c +++ b/tinyusb/host/usbh.c @@ -47,10 +47,14 @@ #include "tusb.h" #include "usbh_hcd.h" +//TODO temporarily +#if TUSB_CFG_OS == TUSB_OS_NONE && !defined(_TEST_) void tusb_tick_tock(void) { osal_tick_tock(); } +#endif + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -129,21 +133,6 @@ tusb_error_t usbh_init(void) return TUSB_ERROR_NONE; } -// interrupt caused by a TD (with IOC=1) in pipe of class class_code -void usbh_isr(pipe_handle_t pipe_hdl, uint8_t class_code) -{ - if (class_code == 0) // Control transfer - { - // TODO some semaphore posting - }else if (usbh_class_drivers[class_code].isr) - { - usbh_class_drivers[class_code].isr(pipe_hdl); - }else - { - ASSERT(false, (void) 0); // something wrong, no one claims the isr's source - } -} - // function called within a task, requesting os blocking services, subtask input parameter must be static/global variables tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, tusb_std_request_t const* p_request, uint8_t* data) { @@ -174,6 +163,35 @@ pipe_status_t usbh_pipe_status_get(pipe_handle_t pipe_hdl) return PIPE_STATUS_BUSY; } +//--------------------------------------------------------------------+ +// USBH-HCD ISR/Callback API +//--------------------------------------------------------------------+ +// interrupt caused by a TD (with IOC=1) in pipe of class class_code +void usbh_isr(pipe_handle_t pipe_hdl, uint8_t class_code) +{ + if (class_code == 0) // Control transfer + { + // TODO some semaphore posting + }else if (usbh_class_drivers[class_code].isr) + { + usbh_class_drivers[class_code].isr(pipe_hdl); + }else + { + ASSERT(false, (void) 0); // something wrong, no one claims the isr's source + } +} + +void usbh_device_plugged_isr(uint8_t hostid, tusb_speed_t speed) +{ + +} + +void usbh_device_unplugged_isr(uint8_t hostid) +{ + +} + + //--------------------------------------------------------------------+ // ENUMERATION TASK //--------------------------------------------------------------------+ diff --git a/tinyusb/host/usbh_hcd.h b/tinyusb/host/usbh_hcd.h index 03901050..bbcad361 100644 --- a/tinyusb/host/usbh_hcd.h +++ b/tinyusb/host/usbh_hcd.h @@ -101,6 +101,9 @@ typedef struct { // TODO internal structure, re-order members extern usbh_device_info_t usbh_device_info_pool[TUSB_CFG_HOST_DEVICE_MAX+1]; // including zero-address void usbh_isr(pipe_handle_t pipe_hdl, uint8_t class_code); +void usbh_device_plugged_isr(uint8_t hostid, tusb_speed_t speed); +void usbh_device_unplugged_isr(uint8_t hostid); + #ifdef __cplusplus }