diff options
| author | hathach <[email protected]> | 2013-10-01 13:53:54 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2013-10-01 13:53:54 +0700 |
| commit | 640b0ec5467eadf153c4a09d53e0a38bae752685 (patch) | |
| tree | 1d589605ee186827ba6bd70958dd9286ca5ac535 /tinyusb/host | |
| parent | 7f4a3fc8294e733a9ba52d20fa16ca6662721126 (diff) | |
- move disconnection handle to enum task --> move tusbh_xxx_unmount is invoked in non-isr context
Diffstat (limited to 'tinyusb/host')
| -rw-r--r-- | tinyusb/host/ehci/ehci.c | 4 | ||||
| -rw-r--r-- | tinyusb/host/hub.c | 2 | ||||
| -rw-r--r-- | tinyusb/host/usbh.c | 60 | ||||
| -rw-r--r-- | tinyusb/host/usbh_hcd.h | 2 |
4 files changed, 43 insertions, 25 deletions
diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c index 9cebff790..756c7dcb9 100644 --- a/tinyusb/host/ehci/ehci.c +++ b/tinyusb/host/ehci/ehci.c @@ -564,11 +564,11 @@ static void port_connect_status_change_isr(uint8_t hostid) // NOTE There is an sequence plug->unplug->…..-> plug if device is powering with pre-plugged device if (regs->portsc_bit.current_connect_status) { - usbh_device_plugged_isr(hostid, 0, 0); + usbh_hcd_rhport_plugged_isr(hostid, 0, 0); }else // device unplugged { usbh_hcd_rhport_unplugged_isr(hostid); - regs->usb_cmd_bit.advacne_async = 1; // Async doorbell check EHCI 4.8.2 for operational details +// regs->usb_cmd_bit.advacne_async = 1; // Async doorbell check EHCI 4.8.2 for operational details } } diff --git a/tinyusb/host/hub.c b/tinyusb/host/hub.c index b4f1baf09..e72a0ac5a 100644 --- a/tinyusb/host/hub.c +++ b/tinyusb/host/hub.c @@ -210,7 +210,7 @@ void hub_isr(pipe_handle_t pipe_hdl, tusb_event_t event, uint32_t xferred_bytes) if ( BIT_TEST_(p_hub->status_change, port) ) { // TODO HUB connection/disconnection will be determined in enum task --> connect change - usbh_device_plugged_isr(usbh_devices[pipe_hdl.dev_addr].core_id, pipe_hdl.dev_addr, port); + usbh_hcd_rhport_plugged_isr(usbh_devices[pipe_hdl.dev_addr].core_id, pipe_hdl.dev_addr, port); } } diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c index 929c87b0e..dcb4e73a8 100644 --- a/tinyusb/host/usbh.c +++ b/tinyusb/host/usbh.c @@ -273,16 +273,21 @@ void usbh_xfer_isr(pipe_handle_t pipe_hdl, uint8_t class_code, tusb_event_t even } } -void usbh_device_plugged_isr(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port) +void usbh_hcd_rhport_plugged_isr(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port) { osal_queue_send(enum_queue_hdl, - &(usbh_enumerate_t){ .core_id = hostid, .hub_addr = hub_addr, .hub_port = hub_port} ); + &(usbh_enumerate_t){ + .core_id = hostid, + .hub_addr = hub_addr, + .hub_port = hub_port} + ); } // a device unplugged on hostid, hub_addr, hub_port // return true if found and unmounted device, false if cannot find -bool usbh_device_unplugged(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port) +void usbh_device_unplugged(uint8_t hostid, 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 <= TUSB_CFG_HOST_DEVICE_MAX; dev_addr ++) { @@ -306,15 +311,24 @@ bool usbh_device_unplugged(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port) // HCD must set this device's state to TUSB_DEVICE_STATE_UNPLUG when done usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_REMOVING; usbh_devices[dev_addr].flag_supported_class = 0; + + is_found = true; } } - return true; + if (is_found) hcd_hub_advance_asyn(usbh_devices[0].core_id); // TODO hack + } void usbh_hcd_rhport_unplugged_isr(uint8_t hostid) { - (void) usbh_device_unplugged(hostid, 0, 0); + osal_queue_send(enum_queue_hdl, + &(usbh_enumerate_t) + { + .core_id = hostid, + .hub_addr = 0, + .hub_port = 0 + } ); } //--------------------------------------------------------------------+ @@ -353,8 +367,23 @@ tusb_error_t enumeration_body_subtask(void) usbh_devices[0].hub_port = enum_entry.hub_port; usbh_devices[0].state = TUSB_DEVICE_STATE_UNPLUG; - if ( usbh_devices[0].hub_addr != 0) // connected/disconnected via hub - { + if ( usbh_devices[0].hub_addr == 0) + { // connected/disconnected directly with roothub + if( hcd_port_connect_status(usbh_devices[0].core_id) ) + { // connection event + osal_task_delay(200); // wait for device is stable + hcd_port_reset( usbh_devices[0].core_id ); // port must be reset to have correct speed operation + // osal_task_delay(50); // TODO reset is recommended to last 50 ms (NXP EHCI passes this) + usbh_devices[0].speed = hcd_port_speed_get( usbh_devices[0].core_id ); + } + else + { // disconnection event + usbh_device_unplugged(usbh_devices[0].core_id, 0, 0); + SUBTASK_EXIT(TUSB_ERROR_NONE); // restart task + } + } + else + { // connected/disconnected via hub //------------- Get Port Status -------------// OSAL_SUBTASK_INVOKED_AND_WAIT( usbh_control_xfer_subtask( usbh_devices[0].hub_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_OTHER), @@ -370,17 +399,14 @@ tusb_error_t enumeration_body_subtask(void) if ( ! ((hub_port_status_response_t *) enum_data_buffer)->status_change.connect_status ) SUBTASK_EXIT(TUSB_ERROR_NONE); // only handle connection change if ( ! ((hub_port_status_response_t *) enum_data_buffer)->status_current.connect_status ) - { // Device is disconnected via Hub - if ( usbh_device_unplugged(usbh_devices[0].core_id, usbh_devices[0].hub_addr, usbh_devices[0].hub_port) ) - { - hcd_hub_advance_asyn(usbh_devices[0].core_id); // TODO hack - } + { // Disconnection event + usbh_device_unplugged(usbh_devices[0].core_id, usbh_devices[0].hub_addr, usbh_devices[0].hub_port); (void) hub_status_pipe_queue( usbh_devices[0].hub_addr ); // done with hub, waiting for next data on status pipe SUBTASK_EXIT(TUSB_ERROR_NONE); // restart task } else - { // Device is connected via Hub + { // Connection Event OSAL_SUBTASK_INVOKED_AND_WAIT ( hub_port_reset_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port), error ); SUBTASK_ASSERT_STATUS( error ); @@ -390,14 +416,6 @@ tusb_error_t enumeration_body_subtask(void) OSAL_SUBTASK_INVOKED_AND_WAIT( hub_port_clear_feature_subtask(usbh_devices[0].hub_addr, usbh_devices[0].hub_port, HUB_FEATURE_PORT_RESET_CHANGE), error ); } } - else - { - SUBTASK_ASSERT( hcd_port_connect_status(usbh_devices[0].core_id) ); // ensure device is still plugged - osal_task_delay(200); // wait for device is stable - hcd_port_reset( usbh_devices[0].core_id ); // port must be reset to have correct speed operation - // osal_task_delay(50); // TODO reset is recommended to last 50 ms (NXP EHCI passes this) - usbh_devices[0].speed = hcd_port_speed_get( usbh_devices[0].core_id ); - } SUBTASK_ASSERT_STATUS( usbh_pipe_control_open(0, 8) ); usbh_devices[0].state = TUSB_DEVICE_STATE_ADDRESSED; diff --git a/tinyusb/host/usbh_hcd.h b/tinyusb/host/usbh_hcd.h index d364dac01..f4e7c7a8c 100644 --- a/tinyusb/host/usbh_hcd.h +++ b/tinyusb/host/usbh_hcd.h @@ -115,7 +115,7 @@ extern usbh_device_info_t usbh_devices[TUSB_CFG_HOST_DEVICE_MAX+1]; // including // callback from HCD ISR //--------------------------------------------------------------------+ void usbh_xfer_isr(pipe_handle_t pipe_hdl, uint8_t class_code, tusb_event_t event, uint32_t xferred_bytes); -void usbh_device_plugged_isr(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port); +void usbh_hcd_rhport_plugged_isr(uint8_t hostid, uint8_t hub_addr, uint8_t hub_port); void usbh_hcd_rhport_unplugged_isr(uint8_t hostid); #ifdef __cplusplus |
