From bbfa85aa08d19f57f6e1c8bb0040839e38d9a01c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Sep 2013 18:23:34 +0700 Subject: [PATCH] allow a limited model to deal with stalled pipe/transaction added stall clear & able to mount the stupid toshiba thumb drive add HCD pipe API - bool hcd_pipe_is_busy(pipe_handle_t pipe_hdl); - bool hcd_pipe_is_stalled(pipe_handle_t pipe_hdl); - uint8_t hcd_pipe_get_endpoint_addr(pipe_handle_t pipe_hdl); - tusb_error_t hcd_pipe_clear_stall(pipe_handle_t pipe_hdl); remove tusbh_device_mount_failed_cb (not neccessary for user) --- demos/host/host_os_none/host_os_none.uvopt | 65 +++++++++++++------ .../test/host/usbh/test_enum_task.c | 12 ++-- tests/lpc18xx_43xx/test/host/usbh/test_usbh.c | 31 ++++++++- tinyusb/class/cdc_host.c | 1 + tinyusb/class/msc_host.c | 56 ++++++++++++---- tinyusb/common/errors.h | 2 + tinyusb/host/ehci/ehci.c | 41 ++++++++++-- tinyusb/host/hcd.h | 5 ++ tinyusb/host/usbh.c | 10 ++- tinyusb/osal/osal.h | 14 ++-- tinyusb/osal/osal_none.h | 3 + 11 files changed, 187 insertions(+), 53 deletions(-) diff --git a/demos/host/host_os_none/host_os_none.uvopt b/demos/host/host_os_none/host_os_none.uvopt index 606ed51f4..cc4fd5522 100644 --- a/demos/host/host_os_none/host_os_none.uvopt +++ b/demos/host/host_os_none/host_os_none.uvopt @@ -185,12 +185,37 @@ 1 ehci_data + + 5 + 1 + ehci_data.device[0].qhd[0] + + + 6 + 1 + ehci_data.device[0].qhd[1] + + + 7 + 1 + msch_semaphore + + + 8 + 1 + ehci_data.device[0].qhd[0].p_qtd_list_head + + + 9 + 1 + ehci_data.device[0].qhd[1].p_qtd_list_head + 1 0 - ITM_RxBuffer + 0x20002067 @@ -421,8 +446,8 @@ 0 0 0 - 1 - 1 + 101 + 107 0 ..\src\main.c main.c @@ -437,8 +462,8 @@ 0 0 0 - 0 - 0 + 127 + 145 0 ..\src\cdc_serial_app.c cdc_serial_app.c @@ -453,8 +478,8 @@ 0 0 0 - 0 - 0 + 169 + 186 0 ..\src\keyboard_app.c keyboard_app.c @@ -469,8 +494,8 @@ 0 0 0 - 0 - 0 + 123 + 126 0 ..\src\mouse_app.c mouse_app.c @@ -693,8 +718,8 @@ 0 0 0 - 0 - 0 + 58 + 76 0 ..\..\..\tinyusb\tusb.c tusb.c @@ -755,10 +780,10 @@ 1 0 0 - 48 + 0 0 - 367 - 374 + 493 + 501 0 ..\..\..\tinyusb\host\usbh.c usbh.c @@ -771,10 +796,10 @@ 1 0 0 - 27 + 0 0 - 1 - 8 + 593 + 605 0 ..\..\..\tinyusb\host\ehci\ehci.c ehci.c @@ -931,10 +956,10 @@ 1 0 0 - 0 + 44 0 1 - 1 + 8 0 ..\..\..\tinyusb\class\msc_host.c msc_host.c @@ -1059,7 +1084,7 @@ 2 0 0 - 9 + 18 0 144 150 diff --git a/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c b/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c index 5d658449f..69b5bb40b 100644 --- a/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c +++ b/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c @@ -210,7 +210,7 @@ void test_addr0_failed_dev_desc(void) { osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(0)); - tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); +// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); usbh_enumeration_task(NULL); @@ -222,7 +222,7 @@ void test_addr0_failed_set_address(void) { osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(1)); hcd_port_reset_Expect( usbh_devices[0].core_id ); - tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); +// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); usbh_enumeration_task(NULL); @@ -239,7 +239,7 @@ void test_enum_failed_get_full_dev_desc(void) osal_semaphore_reset_Expect( usbh_devices[0].control.sem_hdl ); osal_mutex_reset_Expect( usbh_devices[0].control.mutex_hdl ); hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE); - tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); +// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); usbh_enumeration_task(NULL); @@ -261,7 +261,7 @@ void test_enum_failed_get_9byte_config_desc(void) hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE); tusbh_device_attached_cb_ExpectAndReturn((tusb_descriptor_device_t*) enum_data_buffer, 1); - tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); +// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); usbh_enumeration_task(NULL); @@ -279,7 +279,7 @@ void test_enum_failed_get_full_config_desc(void) osal_mutex_reset_Expect( usbh_devices[0].control.mutex_hdl ); hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE); tusbh_device_attached_cb_ExpectAndReturn((tusb_descriptor_device_t*) enum_data_buffer, 1); - tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); +// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); usbh_enumeration_task(NULL); } @@ -294,7 +294,7 @@ void test_enum_parse_config_desc(void) hcd_pipe_control_open_ExpectAndReturn(1, desc_device.bMaxPacketSize0, TUSB_ERROR_NONE); tusbh_device_attached_cb_ExpectAndReturn((tusb_descriptor_device_t*) enum_data_buffer, 1); - tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); // fail to set configure +// tusbh_device_mount_failed_cb_Expect(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL); // fail to set configure usbh_enumeration_task(NULL); diff --git a/tests/lpc18xx_43xx/test/host/usbh/test_usbh.c b/tests/lpc18xx_43xx/test/host/usbh/test_usbh.c index 95e667a6a..961d836df 100644 --- a/tests/lpc18xx_43xx/test/host/usbh/test_usbh.c +++ b/tests/lpc18xx_43xx/test/host/usbh/test_usbh.c @@ -49,6 +49,7 @@ #include "mock_tusb_callback.h" #include "mock_hid_host.h" #include "mock_cdc_host.h" +#include "mock_msc_host.h" #include "host_helper.h" uint8_t dev_addr; @@ -161,7 +162,7 @@ void test_usbh_device_unplugged_isr(void) usbh_devices[dev_addr].hub_port = 0; usbh_devices[dev_addr].flag_supported_class = TUSB_CLASS_FLAG_HID; - helper_class_close_expect(dev_addr); + hidh_close_Expect(dev_addr); hcd_pipe_control_close_ExpectAndReturn(dev_addr, TUSB_ERROR_NONE); //------------- Code Under Test -------------// @@ -170,6 +171,29 @@ void test_usbh_device_unplugged_isr(void) TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_REMOVING, usbh_devices[dev_addr].state); } +void test_usbh_device_unplugged_multple_class(void) +{ + uint8_t dev_addr = 1; + + usbh_devices[dev_addr].state = TUSB_DEVICE_STATE_CONFIGURED; + usbh_devices[dev_addr].core_id = 0; + usbh_devices[dev_addr].hub_addr = 0; + usbh_devices[dev_addr].hub_port = 0; + usbh_devices[dev_addr].flag_supported_class = TUSB_CLASS_FLAG_HID | TUSB_CLASS_FLAG_MSC | TUSB_CLASS_FLAG_CDC; + + cdch_close_Expect(dev_addr); + hidh_close_Expect(dev_addr); + msch_close_Expect(dev_addr); + + hcd_pipe_control_close_ExpectAndReturn(dev_addr, TUSB_ERROR_NONE); + + //------------- Code Under Test -------------// + usbh_device_unplugged_isr(0); + + TEST_ASSERT_EQUAL(TUSB_DEVICE_STATE_REMOVING, usbh_devices[dev_addr].state); + +} + void semaphore_wait_success_stub(osal_mutex_handle_t const sem_hdl, uint32_t msec, tusb_error_t *p_error, int num_call) { (*p_error) = TUSB_ERROR_NONE; @@ -219,3 +243,8 @@ void test_usbh_control_xfer_ok(void) //------------- Code Under Test -------------// usbh_control_xfer_subtask(dev_addr, 1, 2, 3, 4, 0, NULL); } + +//void test_usbh_xfer_isr_non_control_stalled(void) // do nothing for stall on control +//{ +// +//} diff --git a/tinyusb/class/cdc_host.c b/tinyusb/class/cdc_host.c index 15a232184..1fae8d66e 100644 --- a/tinyusb/class/cdc_host.c +++ b/tinyusb/class/cdc_host.c @@ -194,6 +194,7 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con { tusb_descriptor_endpoint_t const *p_endpoint = (tusb_descriptor_endpoint_t const *) p_desc; ASSERT_INT(TUSB_DESC_TYPE_ENDPOINT, p_endpoint->bDescriptorType, TUSB_ERROR_USBH_DESCRIPTOR_CORRUPTED); + ASSERT_INT(TUSB_XFER_BULK, p_endpoint->bmAttributes.xfer, TUSB_ERROR_USBH_DESCRIPTOR_CORRUPTED); pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_DEV_TO_HOST_MASK ) ? &p_cdc->pipe_in : &p_cdc->pipe_out; diff --git a/tinyusb/class/msc_host.c b/tinyusb/class/msc_host.c index 1e11a4b85..9d4c9a258 100644 --- a/tinyusb/class/msc_host.c +++ b/tinyusb/class/msc_host.c @@ -53,6 +53,10 @@ //--------------------------------------------------------------------+ STATIC_VAR msch_interface_t msch_data[TUSB_CFG_HOST_DEVICE_MAX] TUSB_CFG_ATTR_USBRAM; +//------------- Initalization Data -------------// +OSAL_SEM_DEF(msch_semaphore); +static osal_semaphore_handle_t msch_sem_hdl; + // buffer used to read scsi information when mounted, largest reponse data currently is inquiry ATTR_ALIGNED(4) STATIC_VAR uint8_t msch_buffer[sizeof(scsi_inquiry_data_t)] TUSB_CFG_ATTR_USBRAM; @@ -166,6 +170,7 @@ static tusb_error_t scsi_command_send(msch_interface_t * p_msch, scsi_cmd_type_t void msch_init(void) { memclr_(msch_data, sizeof(msch_interface_t)*TUSB_CFG_HOST_DEVICE_MAX); + msch_sem_hdl = osal_semaphore_create( OSAL_SEM_REF(msch_semaphore) ); } tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *p_interface_desc, uint16_t *p_length) @@ -185,6 +190,7 @@ tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con for(uint32_t i=0; i<2; i++) { ASSERT_INT(TUSB_DESC_TYPE_ENDPOINT, p_endpoint->bDescriptorType, TUSB_ERROR_USBH_DESCRIPTOR_CORRUPTED); + ASSERT_INT(TUSB_XFER_BULK, p_endpoint->bmAttributes.xfer, TUSB_ERROR_USBH_DESCRIPTOR_CORRUPTED); pipe_handle_t * p_pipe_hdl = ( p_endpoint->bEndpointAddress & TUSB_DIR_DEV_TO_HOST_MASK ) ? &msch_data[dev_addr-1].bulk_in : &msch_data[dev_addr-1].bulk_out; @@ -198,6 +204,7 @@ tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con msch_data[dev_addr-1].interface_number = p_interface_desc->bInterfaceNumber; (*p_length) += sizeof(tusb_descriptor_interface_t) + 2*sizeof(tusb_descriptor_endpoint_t); + //------------- Get Max Lun -------------// OSAL_SUBTASK_INVOKED_AND_WAIT( usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_INTERFACE), @@ -219,26 +226,45 @@ tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con ); #endif - - // TODO timeout required, a proper synchronization -// while( !hcd_pipe_is_idle(msch_data[dev_addr-1].bulk_in) ) - + enum { SCSI_XFER_TIMEOUT = 1000 }; //------------- SCSI Inquiry -------------// scsi_command_send(&msch_data[dev_addr-1], SCSI_CMD_INQUIRY, 0, msch_buffer); - osal_task_delay(2); + osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error); + SUBTASK_ASSERT_STATUS(error); memcpy(msch_data[dev_addr-1].vendor_id , ((scsi_inquiry_data_t*) msch_buffer)->vendor_id , 8); memcpy(msch_data[dev_addr-1].product_id, ((scsi_inquiry_data_t*) msch_buffer)->product_id, 16); -#if 0 - //------------- SCSI Request Sense -------------// - scsi_command_send(&msch_data[dev_addr-1], SCSI_CMD_REQUEST_SENSE, 0, msch_buffer); - osal_task_delay(2); -#endif - //------------- SCSI Read Capacity 10 -------------// scsi_command_send(&msch_data[dev_addr-1], SCSI_CMD_READ_CAPACITY_10, 0, msch_buffer); - osal_task_delay(2); + osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error); + SUBTASK_ASSERT_STATUS(error); + + // NOTE: my toshiba thumbdrive stall the first Read Capacity and require the sequence + // Read Capacity --> Stalled --> Clear Stall --> Request Sense --> Read Capacity (2) to work + if ( hcd_pipe_is_stalled(msch_data[dev_addr-1].bulk_in) ) + { // clear stall TODO abtract clear stalll function + OSAL_SUBTASK_INVOKED_AND_WAIT( + usbh_control_xfer_subtask( dev_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_ENDPOINT), + TUSB_REQUEST_CLEAR_FEATURE, 0, hcd_pipe_get_endpoint_addr(msch_data[dev_addr-1].bulk_in), + 0, NULL ), + error + ); + + hcd_pipe_clear_stall(msch_data[dev_addr-1].bulk_in); + osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error); + SUBTASK_ASSERT_STATUS(error); + + //------------- SCSI Request Sense -------------// + scsi_command_send(&msch_data[dev_addr-1], SCSI_CMD_REQUEST_SENSE, 0, msch_buffer); + osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error); + SUBTASK_ASSERT_STATUS(error); + + //------------- Re-read SCSI Read Capactity -------------// + scsi_command_send(&msch_data[dev_addr-1], SCSI_CMD_READ_CAPACITY_10, 0, msch_buffer); + osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error); + SUBTASK_ASSERT_STATUS(error); + } msch_data[dev_addr-1].last_lba = __be2le( ((scsi_read_capacity10_data_t*)msch_buffer)->last_lba ); msch_data[dev_addr-1].block_size = (uint16_t) __be2le( ((scsi_read_capacity10_data_t*)msch_buffer)->block_size ); @@ -252,7 +278,10 @@ tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con void msch_isr(pipe_handle_t pipe_hdl, tusb_event_t event, uint32_t xferred_bytes) { - + if ( pipehandle_is_equal(pipe_hdl, msch_data[pipe_hdl.dev_addr-1].bulk_in) ) + { + osal_semaphore_post(msch_sem_hdl); + } } void msch_close(uint8_t dev_addr) @@ -261,6 +290,7 @@ void msch_close(uint8_t dev_addr) (void) hcd_pipe_close(msch_data[dev_addr-1].bulk_out); memclr_(&msch_data[dev_addr-1], sizeof(msch_interface_t)); + osal_semaphore_reset(msch_sem_hdl); } //--------------------------------------------------------------------+ diff --git a/tinyusb/common/errors.h b/tinyusb/common/errors.h index 96681624c..77461f568 100644 --- a/tinyusb/common/errors.h +++ b/tinyusb/common/errors.h @@ -69,6 +69,8 @@ ENTRY(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND )\ ENTRY(TUSB_ERROR_USBH_MOUNT_CONFIG_DESC_TOO_LONG )\ ENTRY(TUSB_ERROR_USBH_DESCRIPTOR_CORRUPTED )\ + ENTRY(TUSB_ERROR_USBH_XFER_STALLED )\ + ENTRY(TUSB_ERROR_USBH_XFER_FAILED )\ ENTRY(TUSB_ERROR_OSAL_TIMEOUT )\ ENTRY(TUSB_ERROR_OSAL_WAITING ) /* only used by OSAL_NONE in the subtask */ \ ENTRY(TUSB_ERROR_OSAL_TASK_FAILED )\ diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c index 40c59616e..684051917 100644 --- a/tinyusb/host/ehci/ehci.c +++ b/tinyusb/host/ehci/ehci.c @@ -100,6 +100,13 @@ static inline ehci_qhd_t* qhd_find_free (uint8_t dev_addr) ATTR_PURE ATTR_ALW static inline tusb_xfer_type_t qhd_get_xfer_type(ehci_qhd_t const * p_qhd) ATTR_ALWAYS_INLINE ATTR_PURE; STATIC_ INLINE_ ehci_qhd_t* qhd_get_from_pipe_handle(pipe_handle_t pipe_hdl) ATTR_PURE ATTR_ALWAYS_INLINE; static inline pipe_handle_t qhd_create_pipe_handle(ehci_qhd_t const * p_qhd, tusb_xfer_type_t xfer_type) ATTR_PURE ATTR_ALWAYS_INLINE; +// determine if a queue head has bus-related error +static inline bool qhd_has_xact_error(ehci_qhd_t * p_qhd) ATTR_ALWAYS_INLINE ATTR_PURE; +static inline bool qhd_has_xact_error(ehci_qhd_t * p_qhd) +{ + return ( p_qhd->qtd_overlay.buffer_err ||p_qhd->qtd_overlay.babble_err || p_qhd->qtd_overlay.xact_err ); + //p_qhd->qtd_overlay.non_hs_period_missed_uframe || p_qhd->qtd_overlay.pingstate_err TODO split transaction error +} static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, uint16_t max_packet_size, uint8_t endpoint_addr, uint8_t xfer_type, uint8_t interval); @@ -468,12 +475,38 @@ tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl) return TUSB_ERROR_NONE; } +bool hcd_pipe_is_busy(pipe_handle_t pipe_hdl) +{ + ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl ); + return !p_qhd->qtd_overlay.halted && (p_qhd->p_qtd_list_head != NULL); +} + bool hcd_pipe_is_idle(pipe_handle_t pipe_hdl) { ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl ); return (p_qhd->p_qtd_list_head == NULL); } +bool hcd_pipe_is_stalled(pipe_handle_t pipe_hdl) +{ + ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl ); + return p_qhd->qtd_overlay.halted && !qhd_has_xact_error(p_qhd); +} + +uint8_t hcd_pipe_get_endpoint_addr(pipe_handle_t pipe_hdl) +{ + ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl ); + return p_qhd->endpoint_number + ( (p_qhd->pid_non_control == EHCI_PID_IN) ? 0x80 : 0); +} + +tusb_error_t hcd_pipe_clear_stall(pipe_handle_t pipe_hdl) +{ + ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl ); + p_qhd->qtd_overlay.halted = 0; + + return TUSB_ERROR_NONE; +} + //--------------------------------------------------------------------+ // EHCI Interrupt Handler //--------------------------------------------------------------------+ @@ -617,16 +650,14 @@ static void period_list_xfer_complete_isr(uint8_t hostid, uint8_t interval_ms) static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd) { - if ( (p_qhd->device_address != 0 && p_qhd->qtd_overlay.halted) || // addr0 cannot be protocol STALL - p_qhd->qtd_overlay.buffer_err ||p_qhd->qtd_overlay.babble_err || p_qhd->qtd_overlay.xact_err ) - //p_qhd->qtd_overlay.non_hs_period_missed_uframe || p_qhd->qtd_overlay.pingstate_err TODO split transaction error + if ( (p_qhd->device_address != 0 && p_qhd->qtd_overlay.halted) || // addr0 cannot be protocol STALL + qhd_has_xact_error(p_qhd) ) { // current qhd has error in transaction tusb_xfer_type_t const xfer_type = qhd_get_xfer_type(p_qhd); tusb_event_t error_event; // no error bits are set, endpoint is halted due to STALL - error_event = ( !(p_qhd->qtd_overlay.buffer_err || p_qhd->qtd_overlay.babble_err || - p_qhd->qtd_overlay.xact_err) ) ? TUSB_EVENT_XFER_STALLED : TUSB_EVENT_XFER_ERROR; + error_event = qhd_has_xact_error(p_qhd) ? TUSB_EVENT_XFER_ERROR : TUSB_EVENT_XFER_STALLED; p_qhd->total_xferred_bytes += p_qhd->p_qtd_list_head->expected_bytes - p_qhd->p_qtd_list_head->total_bytes; diff --git a/tinyusb/host/hcd.h b/tinyusb/host/hcd.h index 61642d95b..6383015a8 100644 --- a/tinyusb/host/hcd.h +++ b/tinyusb/host/hcd.h @@ -98,7 +98,12 @@ pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const * tusb_error_t hcd_pipe_queue_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes) ATTR_WARN_UNUSED_RESULT; // only queue, not transferring yet tusb_error_t hcd_pipe_xfer(pipe_handle_t pipe_hdl, uint8_t buffer[], uint16_t total_bytes, bool int_on_complete) ATTR_WARN_UNUSED_RESULT; tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl) /*ATTR_WARN_UNUSED_RESULT*/; + +bool hcd_pipe_is_busy(pipe_handle_t pipe_hdl); +bool hcd_pipe_is_stalled(pipe_handle_t pipe_hdl); bool hcd_pipe_is_idle(pipe_handle_t pipe_hdl); +uint8_t hcd_pipe_get_endpoint_addr(pipe_handle_t pipe_hdl); +tusb_error_t hcd_pipe_clear_stall(pipe_handle_t pipe_hdl); #if 0 tusb_error_t hcd_pipe_cancel()ATTR_WARN_UNUSED_RESULT; diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c index 67cc8f96c..65efe8768 100644 --- a/tinyusb/host/usbh.c +++ b/tinyusb/host/usbh.c @@ -216,9 +216,13 @@ tusb_error_t usbh_control_xfer_subtask(uint8_t dev_addr, uint8_t bmRequestType, osal_mutex_release(usbh_devices[dev_addr].control.mutex_hdl); // TODO make handler for this function general purpose - SUBTASK_ASSERT_WITH_HANDLER(TUSB_ERROR_NONE == error && - TUSB_EVENT_XFER_COMPLETE == usbh_devices[dev_addr].control.pipe_status, - tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) ); + if (TUSB_ERROR_NONE != error) SUBTASK_EXIT(error); + if (TUSB_EVENT_XFER_STALLED == usbh_devices[dev_addr].control.pipe_status) SUBTASK_EXIT(TUSB_ERROR_USBH_XFER_STALLED); + if (TUSB_EVENT_XFER_ERROR == usbh_devices[dev_addr].control.pipe_status) SUBTASK_EXIT(TUSB_ERROR_USBH_XFER_FAILED); + +// SUBTASK_ASSERT_WITH_HANDLER(TUSB_ERROR_NONE == error && +// TUSB_EVENT_XFER_COMPLETE == usbh_devices[dev_addr].control.pipe_status, +// tusbh_device_mount_failed_cb(TUSB_ERROR_USBH_MOUNT_DEVICE_NOT_RESPOND, NULL) ); OSAL_SUBTASK_END } diff --git a/tinyusb/osal/osal.h b/tinyusb/osal/osal.h index d2287b3a5..d23cb518c 100644 --- a/tinyusb/osal/osal.h +++ b/tinyusb/osal/osal.h @@ -68,16 +68,20 @@ #if TUSB_CFG_OS == TUSB_OS_NONE #include "osal_none.h" -#elif TUSB_CFG_OS == TUSB_OS_FREERTOS - #include "osal_freeRTOS.h" -#elif TUSB_CFG_OS == TUSB_OS_CMSIS_RTX - #include "osal_cmsis_rtx.h" #else - #error TUSB_CFG_OS is not defined or OS is not supported yet + #define OSAL_VAR + #if TUSB_CFG_OS == TUSB_OS_FREERTOS + #include "osal_freeRTOS.h" + #elif TUSB_CFG_OS == TUSB_OS_CMSIS_RTX + #include "osal_cmsis_rtx.h" + #else + #error TUSB_CFG_OS is not defined or OS is not supported yet + #endif #endif #else // OSAL API for cmock +#define OSAL_VAR #include "osal_common.h" //------------- Tick -------------// diff --git a/tinyusb/osal/osal_none.h b/tinyusb/osal/osal_none.h index 853f33e67..775febc3f 100644 --- a/tinyusb/osal/osal_none.h +++ b/tinyusb/osal/osal_none.h @@ -58,6 +58,9 @@ extern "C" { #endif +// variable that retains value after OSAL blocking service need to declare with OSAL_VAR +#define OSAL_VAR static + //--------------------------------------------------------------------+ // TICK API //--------------------------------------------------------------------+