mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-02 04:20:29 +00:00
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)
This commit is contained in:
parent
63b776f7cf
commit
bbfa85aa08
demos/host/host_os_none
tests/lpc18xx_43xx/test/host/usbh
tinyusb
@ -185,12 +185,37 @@
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>ehci_data</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>5</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>ehci_data.device[0].qhd[0]</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>6</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>ehci_data.device[0].qhd[1]</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>7</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>msch_semaphore</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>8</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>ehci_data.device[0].qhd[0].p_qtd_list_head</ItemText>
|
||||
</Ww>
|
||||
<Ww>
|
||||
<count>9</count>
|
||||
<WinNumber>1</WinNumber>
|
||||
<ItemText>ehci_data.device[0].qhd[1].p_qtd_list_head</ItemText>
|
||||
</Ww>
|
||||
</WatchWindow1>
|
||||
<MemoryWindow1>
|
||||
<Mm>
|
||||
<WinNumber>1</WinNumber>
|
||||
<SubType>0</SubType>
|
||||
<ItemText>ITM_RxBuffer</ItemText>
|
||||
<ItemText>0x20002067</ItemText>
|
||||
</Mm>
|
||||
</MemoryWindow1>
|
||||
<DebugFlag>
|
||||
@ -421,8 +446,8 @@
|
||||
<Focus>0</Focus>
|
||||
<ColumnNumber>0</ColumnNumber>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<TopLine>1</TopLine>
|
||||
<CurrentLine>1</CurrentLine>
|
||||
<TopLine>101</TopLine>
|
||||
<CurrentLine>107</CurrentLine>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\src\main.c</PathWithFileName>
|
||||
<FilenameWithoutPath>main.c</FilenameWithoutPath>
|
||||
@ -437,8 +462,8 @@
|
||||
<Focus>0</Focus>
|
||||
<ColumnNumber>0</ColumnNumber>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<TopLine>0</TopLine>
|
||||
<CurrentLine>0</CurrentLine>
|
||||
<TopLine>127</TopLine>
|
||||
<CurrentLine>145</CurrentLine>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\src\cdc_serial_app.c</PathWithFileName>
|
||||
<FilenameWithoutPath>cdc_serial_app.c</FilenameWithoutPath>
|
||||
@ -453,8 +478,8 @@
|
||||
<Focus>0</Focus>
|
||||
<ColumnNumber>0</ColumnNumber>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<TopLine>0</TopLine>
|
||||
<CurrentLine>0</CurrentLine>
|
||||
<TopLine>169</TopLine>
|
||||
<CurrentLine>186</CurrentLine>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\src\keyboard_app.c</PathWithFileName>
|
||||
<FilenameWithoutPath>keyboard_app.c</FilenameWithoutPath>
|
||||
@ -469,8 +494,8 @@
|
||||
<Focus>0</Focus>
|
||||
<ColumnNumber>0</ColumnNumber>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<TopLine>0</TopLine>
|
||||
<CurrentLine>0</CurrentLine>
|
||||
<TopLine>123</TopLine>
|
||||
<CurrentLine>126</CurrentLine>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\src\mouse_app.c</PathWithFileName>
|
||||
<FilenameWithoutPath>mouse_app.c</FilenameWithoutPath>
|
||||
@ -693,8 +718,8 @@
|
||||
<Focus>0</Focus>
|
||||
<ColumnNumber>0</ColumnNumber>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<TopLine>0</TopLine>
|
||||
<CurrentLine>0</CurrentLine>
|
||||
<TopLine>58</TopLine>
|
||||
<CurrentLine>76</CurrentLine>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\tinyusb\tusb.c</PathWithFileName>
|
||||
<FilenameWithoutPath>tusb.c</FilenameWithoutPath>
|
||||
@ -755,10 +780,10 @@
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<ColumnNumber>48</ColumnNumber>
|
||||
<ColumnNumber>0</ColumnNumber>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<TopLine>367</TopLine>
|
||||
<CurrentLine>374</CurrentLine>
|
||||
<TopLine>493</TopLine>
|
||||
<CurrentLine>501</CurrentLine>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\tinyusb\host\usbh.c</PathWithFileName>
|
||||
<FilenameWithoutPath>usbh.c</FilenameWithoutPath>
|
||||
@ -771,10 +796,10 @@
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<ColumnNumber>27</ColumnNumber>
|
||||
<ColumnNumber>0</ColumnNumber>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<TopLine>1</TopLine>
|
||||
<CurrentLine>8</CurrentLine>
|
||||
<TopLine>593</TopLine>
|
||||
<CurrentLine>605</CurrentLine>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\tinyusb\host\ehci\ehci.c</PathWithFileName>
|
||||
<FilenameWithoutPath>ehci.c</FilenameWithoutPath>
|
||||
@ -931,10 +956,10 @@
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<ColumnNumber>0</ColumnNumber>
|
||||
<ColumnNumber>44</ColumnNumber>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<TopLine>1</TopLine>
|
||||
<CurrentLine>1</CurrentLine>
|
||||
<CurrentLine>8</CurrentLine>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\tinyusb\class\msc_host.c</PathWithFileName>
|
||||
<FilenameWithoutPath>msc_host.c</FilenameWithoutPath>
|
||||
@ -1059,7 +1084,7 @@
|
||||
<FileType>2</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<Focus>0</Focus>
|
||||
<ColumnNumber>9</ColumnNumber>
|
||||
<ColumnNumber>18</ColumnNumber>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<TopLine>144</TopLine>
|
||||
<CurrentLine>150</CurrentLine>
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
//{
|
||||
//
|
||||
//}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
@ -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 )\
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 -------------//
|
||||
|
@ -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
|
||||
//--------------------------------------------------------------------+
|
||||
|
Loading…
x
Reference in New Issue
Block a user