diff --git a/demos/bsp/boards/embedded_artists/board_ea4357.h b/demos/bsp/boards/embedded_artists/board_ea4357.h
index 2a6ef8490..3fbf1ecf6 100644
--- a/demos/bsp/boards/embedded_artists/board_ea4357.h
+++ b/demos/bsp/boards/embedded_artists/board_ea4357.h
@@ -66,8 +66,8 @@
#include "oem_base_board/pca9532.h" // LEDs
-//#define CFG_PRINTF_TARGET PRINTF_TARGET_SWO
-#define CFG_PRINTF_TARGET PRINTF_TARGET_UART // FIXME keil's cmsis rtx does not work with UART (work with SWO)
+#define CFG_PRINTF_TARGET PRINTF_TARGET_SWO
+//#define CFG_PRINTF_TARGET PRINTF_TARGET_UART // FIXME keil's cmsis rtx does not work with UART (work with SWO)
/*=========================================================================
HARDWARE MAC ADDRESS
diff --git a/demos/host/host_os_none/host_os_none.uvopt b/demos/host/host_os_none/host_os_none.uvopt
index 45e4c5025..606ed51f4 100644
--- a/demos/host/host_os_none/host_os_none.uvopt
+++ b/demos/host/host_os_none/host_os_none.uvopt
@@ -135,7 +135,7 @@
0
DLGUARM
- (106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0)
+
0
@@ -180,7 +180,19 @@
1
keyboard_data
+
+ 4
+ 1
+ ehci_data
+
+
+
+ 1
+ 0
+ ITM_RxBuffer
+
+
0
1
@@ -201,7 +213,7 @@
0
0
0
- 0
+ 1
0
0
0
@@ -425,8 +437,8 @@
0
0
0
- 95
- 107
+ 0
+ 0
0
..\src\cdc_serial_app.c
cdc_serial_app.c
@@ -441,8 +453,8 @@
0
0
0
- 1
- 1
+ 0
+ 0
0
..\src\keyboard_app.c
keyboard_app.c
@@ -455,10 +467,10 @@
1
0
0
- 43
+ 0
0
- 113
- 127
+ 0
+ 0
0
..\src\mouse_app.c
mouse_app.c
@@ -489,8 +501,8 @@
0
0
0
- 0
- 0
+ 1
+ 1
0
..\src\msc_app.c
msc_app.c
@@ -513,8 +525,8 @@
0
31
0
- 33
- 55
+ 0
+ 0
0
..\..\bsp\boards\board.c
board.c
@@ -529,8 +541,8 @@
0
2
0
- 143
- 146
+ 0
+ 0
0
..\..\bsp\boards\embedded_artists\board_ea4357.c
board_ea4357.c
@@ -543,10 +555,10 @@
1
0
0
- 1
+ 0
0
- 96
- 106
+ 0
+ 0
0
..\..\bsp\boards\printf_retarget.c
printf_retarget.c
@@ -681,8 +693,8 @@
0
0
0
- 23
- 69
+ 0
+ 0
0
..\..\..\tinyusb\tusb.c
tusb.c
@@ -743,10 +755,10 @@
1
0
0
- 0
+ 48
0
- 1
- 1
+ 367
+ 374
0
..\..\..\tinyusb\host\usbh.c
usbh.c
@@ -759,10 +771,10 @@
1
0
0
- 0
+ 27
0
1
- 1
+ 8
0
..\..\..\tinyusb\host\ehci\ehci.c
ehci.c
@@ -807,10 +819,10 @@
1
0
0
- 8
+ 40
0
- 67
- 77
+ 0
+ 0
0
..\..\..\tinyusb\hal\hal_lpc43xx.c
hal_lpc43xx.c
@@ -871,10 +883,10 @@
1
0
0
- 51
+ 78
0
- 1
- 17
+ 0
+ 0
0
..\..\..\tinyusb\class\cdc_host.c
cdc_host.c
@@ -889,8 +901,8 @@
0
0
0
- 1
- 1
+ 0
+ 0
0
..\..\..\tinyusb\class\cdc_rndis_host.c
cdc_rndis_host.c
@@ -903,10 +915,10 @@
1
0
0
- 63
+ 0
0
- 264
- 286
+ 1
+ 1
0
..\..\..\tinyusb\class\hid_host.c
hid_host.c
@@ -1047,10 +1059,10 @@
2
0
0
- 25
+ 9
0
- 138
- 161
+ 144
+ 150
0
..\..\bsp\lpc43xx\startup_keil\startup_LPC43xx.s
startup_LPC43xx.s
diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_ehci_usbh_hcd_integration.c b/tests/lpc18xx_43xx/test/host/ehci/test_ehci_usbh_hcd_integration.c
index 424710b57..2b6de2d44 100644
--- a/tests/lpc18xx_43xx/test/host/ehci/test_ehci_usbh_hcd_integration.c
+++ b/tests/lpc18xx_43xx/test/host/ehci/test_ehci_usbh_hcd_integration.c
@@ -46,6 +46,7 @@
#include "hal.h"
#include "mock_osal.h"
#include "mock_hid_host.h"
+#include "mock_msc_host.h"
#include "mock_cdc_host.h"
#include "hcd.h"
diff --git a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c
index 17a08f2b8..f5f4a0d76 100644
--- a/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c
+++ b/tests/lpc18xx_43xx/test/host/ehci/test_pipe_control_xfer.c
@@ -253,6 +253,13 @@ void test_control_xfer_error_isr(void)
ehci_controller_run_error(hostid);
TEST_ASSERT_EQUAL(0, p_control_qhd->total_xferred_bytes);
+
+ TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_head );
+ TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_tail );
+
+ TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.next.terminate);
+ TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.alternate.terminate);
+ TEST_ASSERT_FALSE( p_control_qhd->qtd_overlay.halted);
}
void test_control_xfer_error_stall(void)
@@ -265,4 +272,18 @@ void test_control_xfer_error_stall(void)
ehci_controller_run_stall(hostid);
TEST_ASSERT_EQUAL(0, p_control_qhd->total_xferred_bytes);
+
+ TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_head );
+ TEST_ASSERT_NULL( p_control_qhd->p_qtd_list_tail );
+
+ TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.next.terminate);
+ TEST_ASSERT_TRUE( p_control_qhd->qtd_overlay.alternate.terminate);
+ TEST_ASSERT_FALSE( p_control_qhd->qtd_overlay.halted);
+
+ #if 0 // no neeed
+ TEST_ASSERT_FALSE( p_setup->used );
+ TEST_ASSERT_FALSE( p_data->used );
+ TEST_ASSERT_FALSE( p_status->used );
+ #endif
}
+
diff --git a/tests/lpc18xx_43xx/test/host/hid/test_hid_host.c b/tests/lpc18xx_43xx/test/host/hid/test_hid_host.c
index d2f9f3063..abf80ac57 100644
--- a/tests/lpc18xx_43xx/test/host/hid/test_hid_host.c
+++ b/tests/lpc18xx_43xx/test/host/hid/test_hid_host.c
@@ -42,6 +42,7 @@
#include "errors.h"
#include "binary.h"
#include "type_helper.h"
+#include "common/common.h"
#include "descriptor_test.h"
#include "mock_osal.h"
diff --git a/tests/lpc18xx_43xx/test/host/hid/test_hidh_generic.c b/tests/lpc18xx_43xx/test/host/hid/test_hidh_generic.c
index f367fb821..8d6c2704d 100644
--- a/tests/lpc18xx_43xx/test/host/hid/test_hidh_generic.c
+++ b/tests/lpc18xx_43xx/test/host/hid/test_hidh_generic.c
@@ -44,8 +44,10 @@
#include "hid_host.h"
#include "mock_osal.h"
#include "mock_cdc_host.h"
-#include "usbh.h"
+#include "mock_msc_host.h"
+
#include "mock_hcd.h"
+#include "usbh.h"
#include "mock_hidh_callback.h"
#include "descriptor_test.h"
#include "host_helper.h"
diff --git a/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c b/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c
index 3cbc5c868..fbc6b33f6 100644
--- a/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c
+++ b/tests/lpc18xx_43xx/test/host/hid/test_hidh_keyboard.c
@@ -118,7 +118,7 @@ void test_keyboard_is_supported_ok(void)
TEST_ASSERT_TRUE( tusbh_hid_keyboard_is_mounted(dev_addr) );
}
-static tusb_error_t stub_set_idle_request(uint8_t address, tusb_control_request_t const* p_request, uint8_t* data, int num_call)
+tusb_error_t stub_set_idle_request(uint8_t address, tusb_control_request_t const* p_request, uint8_t* data, int num_call)
{
TEST_ASSERT_EQUAL( dev_addr, address);
@@ -143,7 +143,9 @@ void test_keyboard_open_ok(void)
hidh_init();
- usbh_control_xfer_subtask_StubWithCallback(stub_set_idle_request);
+ usbh_control_xfer_subtask_ExpectAndReturn(dev_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_INTERFACE),
+ HID_REQUEST_CONTROL_SET_IDLE, 0, p_kbd_interface_desc->bInterfaceNumber, 0, NULL,
+ TUSB_ERROR_NONE);
hcd_pipe_open_ExpectAndReturn(dev_addr, p_kdb_endpoint_desc, TUSB_CLASS_HID, pipe_hdl);
tusbh_hid_keyboard_mounted_cb_Expect(dev_addr);
diff --git a/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c b/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c
index 010286ccb..89d1bb7b6 100644
--- a/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c
+++ b/tests/lpc18xx_43xx/test/host/hid/test_hidh_mouse.c
@@ -107,24 +107,6 @@ void test_mouse_is_supported_ok(void)
TEST_ASSERT_TRUE( tusbh_hid_mouse_is_mounted(dev_addr) );
}
-static tusb_error_t stub_set_idle_request(uint8_t address, tusb_control_request_t const* p_request, uint8_t* data, int num_call)
-{
- TEST_ASSERT_EQUAL( dev_addr, address);
-
- //------------- expecting Set Idle with value = 0 -------------//
- TEST_ASSERT_NOT_NULL( p_request );
- TEST_ASSERT_EQUAL(TUSB_DIR_HOST_TO_DEV , p_request->bmRequestType_bit.direction);
- TEST_ASSERT_EQUAL(TUSB_REQUEST_TYPE_CLASS , p_request->bmRequestType_bit.type);
- TEST_ASSERT_EQUAL(TUSB_REQUEST_RECIPIENT_INTERFACE , p_request->bmRequestType_bit.recipient);
- TEST_ASSERT_EQUAL(HID_REQUEST_CONTROL_SET_IDLE , p_request->bRequest);
- TEST_ASSERT_EQUAL(0 , p_request->wValue);
- TEST_ASSERT_EQUAL(p_mouse_interface_desc->bInterfaceNumber , p_request->wIndex);
-
- TEST_ASSERT_NULL(data);
-
- return TUSB_ERROR_NONE;
-}
-
void test_mouse_open_ok(void)
{
uint16_t length=0;
@@ -132,7 +114,9 @@ void test_mouse_open_ok(void)
hidh_init();
- usbh_control_xfer_subtask_StubWithCallback(stub_set_idle_request);
+ usbh_control_xfer_subtask_ExpectAndReturn(dev_addr, bm_request_type(TUSB_DIR_HOST_TO_DEV, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_INTERFACE),
+ HID_REQUEST_CONTROL_SET_IDLE, 0, p_mouse_interface_desc->bInterfaceNumber, 0, NULL,
+ TUSB_ERROR_NONE);
hcd_pipe_open_ExpectAndReturn(dev_addr, p_mouse_endpoint_desc, TUSB_CLASS_HID, pipe_hdl);
tusbh_hid_mouse_mounted_cb_Expect(dev_addr);
diff --git a/tests/lpc18xx_43xx/test/host/host_helper.h b/tests/lpc18xx_43xx/test/host/host_helper.h
index a81ce37d9..90ef24976 100644
--- a/tests/lpc18xx_43xx/test/host/host_helper.h
+++ b/tests/lpc18xx_43xx/test/host/host_helper.h
@@ -41,7 +41,7 @@
#include "host/usbh_hcd.h"
static inline void helper_class_init_expect(void)
-{
+{ // class code number order
#if TUSB_CFG_HOST_CDC
cdch_init_Expect();
#endif
@@ -50,22 +50,20 @@ static inline void helper_class_init_expect(void)
hidh_init_Expect();
#endif
+#if TUSB_CFG_HOST_MSC
+ msch_init_Expect();
+#endif
+
//TODO update more classes
}
-static inline void helper_class_close_expect(uint8_t dev_addr)
-{
- hidh_close_Expect(dev_addr);
- //TODO update more classes
-}
-
-
static inline void helper_usbh_init_expect(void)
{
- osal_semaphore_create_IgnoreAndReturn( (osal_semaphore_handle_t) 0x1234);
osal_queue_create_IgnoreAndReturn( (osal_queue_handle_t) 0x4566 );
osal_task_create_IgnoreAndReturn(TUSB_ERROR_NONE);
+
+ osal_semaphore_create_IgnoreAndReturn( (osal_semaphore_handle_t) 0x1234);
osal_mutex_create_IgnoreAndReturn((osal_mutex_handle_t) 0x789a);
}
diff --git a/tests/lpc18xx_43xx/test/host/msc/msch_callback.h b/tests/lpc18xx_43xx/test/host/msc/msch_callback.h
new file mode 100644
index 000000000..b91db23fe
--- /dev/null
+++ b/tests/lpc18xx_43xx/test/host/msc/msch_callback.h
@@ -0,0 +1,66 @@
+/**************************************************************************/
+/*!
+ @file msch_callback.h
+ @author hathach (tinyusb.org)
+
+ @section LICENSE
+
+ Software License Agreement (BSD License)
+
+ Copyright (c) 2013, hathach (tinyusb.org)
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ This file is part of the tinyusb stack.
+*/
+/**************************************************************************/
+
+/** \ingroup TBD
+ * \defgroup TBD
+ * \brief TBD
+ *
+ * @{
+ */
+
+#ifndef _TUSB_MSCH_CALLBACK_H_
+#define _TUSB_MSCH_CALLBACK_H_
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "common/common.h"
+
+void tusbh_msc_mounted_cb(uint8_t dev_addr);
+void tusbh_msc_unmounted_isr(uint8_t dev_addr);
+void tusbh_msc_isr(uint8_t dev_addr, tusb_event_t event);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* _TUSB_MSCH_CALLBACK_H_ */
+
+/** @} */
diff --git a/tests/lpc18xx_43xx/test/host/msc/test_msc_host.c b/tests/lpc18xx_43xx/test/host/msc/test_msc_host.c
index 4e42b3023..75a7549d5 100644
--- a/tests/lpc18xx_43xx/test/host/msc/test_msc_host.c
+++ b/tests/lpc18xx_43xx/test/host/msc/test_msc_host.c
@@ -43,21 +43,108 @@
#include "binary.h"
#include "type_helper.h"
-//#include "descriptor_test.h"
-//#include "msc_host.h"
-//#include "usbh.h"
-//#include "hcd.h"
-//#include "ehci.h"
+#include "descriptor_test.h"
+#include "mock_osal.h"
+#include "mock_hcd.h"
+#include "mock_usbh.h"
+
+#include "mock_msch_callback.h"
+#include "msc_host.h"
+
+extern msch_interface_t msch_data[TUSB_CFG_HOST_DEVICE_MAX];
+
+static tusb_descriptor_interface_t const *p_msc_interface_desc = &desc_configuration.msc_interface;
+static tusb_descriptor_endpoint_t const *p_edp_in = &desc_configuration.msc_endpoint_in;
+static tusb_descriptor_endpoint_t const *p_edp_out = &desc_configuration.msc_endpoint_out;
+
+static msch_interface_t* p_msc;
+
+static uint8_t dev_addr;
+static pipe_handle_t pipe_in, pipe_out;
+static pipe_handle_t const pipe_null = { 0 };
+static uint16_t length;
void setUp(void)
{
+ dev_addr = RANDOM(TUSB_CFG_HOST_DEVICE_MAX)+1;
+
+ msch_init();
+ TEST_ASSERT_MEM_ZERO(msch_data, sizeof(msch_interface_t)*TUSB_CFG_HOST_DEVICE_MAX);
+
+ p_msc = &msch_data[dev_addr-1];
+ pipe_in = (pipe_handle_t) {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_BULK, .index = 1};
+ pipe_out = (pipe_handle_t) {.dev_addr = dev_addr, .xfer_type = TUSB_XFER_BULK, .index = 2};
}
void tearDown(void)
{
+ length = 0;
}
-void test_()
+void test_open_pipe_in_failed(void)
{
- // TEST_IGNORE();
+ hcd_pipe_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, pipe_null);
+
+ TEST_ASSERT_EQUAL(TUSB_ERROR_HCD_OPEN_PIPE_FAILED, msch_open_subtask(dev_addr, p_msc_interface_desc, &length));
}
+
+void test_open_pipe_out_failed(void)
+{
+ hcd_pipe_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, (pipe_handle_t) {1} );
+ hcd_pipe_open_ExpectAndReturn(dev_addr, p_edp_out, TUSB_CLASS_MSC, pipe_null);
+
+ TEST_ASSERT_EQUAL(TUSB_ERROR_HCD_OPEN_PIPE_FAILED, msch_open_subtask(dev_addr, p_msc_interface_desc, &length));
+}
+
+tusb_error_t stub_control_xfer(uint8_t dev_addr, uint8_t bmRequestType, uint8_t bRequest,
+ uint16_t wValue, uint16_t wIndex, uint16_t wLength, uint8_t* data, int num_call)
+{
+ switch ( num_call )
+ {
+ case 0: // get max lun
+ TEST_ASSERT_EQUAL(bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_CLASS, TUSB_REQUEST_RECIPIENT_INTERFACE),
+ bmRequestType);
+ TEST_ASSERT_EQUAL(MSC_REQUEST_GET_MAX_LUN, bRequest);
+ TEST_ASSERT_EQUAL(p_msc_interface_desc->bInterfaceNumber, wIndex);
+ TEST_ASSERT_EQUAL(1, wLength);
+ *data = 1; // TODO multiple LUN support
+ break;
+
+ default:
+ TEST_FAIL();
+ return TUSB_ERROR_FAILED;
+ }
+
+ return TUSB_ERROR_NONE;
+}
+
+void test_open_desc_length(void)
+{
+ hcd_pipe_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, pipe_in);
+ hcd_pipe_open_ExpectAndReturn(dev_addr, p_edp_out, TUSB_CLASS_MSC, pipe_out);
+
+ usbh_control_xfer_subtask_IgnoreAndReturn(TUSB_ERROR_NONE);
+ hcd_pipe_xfer_IgnoreAndReturn(TUSB_ERROR_NONE);
+ hcd_pipe_queue_xfer_IgnoreAndReturn(TUSB_ERROR_NONE);
+
+ //------------- Code Under Test -------------//
+ TEST_ASSERT_STATUS( msch_open_subtask(dev_addr, p_msc_interface_desc, &length) );
+
+ TEST_ASSERT_EQUAL(sizeof(tusb_descriptor_interface_t) + 2*sizeof(tusb_descriptor_endpoint_t),
+ length);
+}
+
+void test_open_ok(void)
+{
+ hcd_pipe_open_ExpectAndReturn(dev_addr, p_edp_in, TUSB_CLASS_MSC, pipe_in);
+ hcd_pipe_open_ExpectAndReturn(dev_addr, p_edp_out, TUSB_CLASS_MSC, pipe_out);
+
+ //------------- get max lun -------------//
+ usbh_control_xfer_subtask_StubWithCallback(stub_control_xfer);
+
+ //------------- Code Under Test -------------//
+ TEST_ASSERT_STATUS( msch_open_subtask(dev_addr, p_msc_interface_desc, &length) );
+
+ TEST_ASSERT_EQUAL(p_msc_interface_desc->bInterfaceNumber, p_msc->interface_number);
+}
+
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 b036084d3..5d658449f 100644
--- a/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c
+++ b/tests/lpc18xx_43xx/test/host/usbh/test_enum_task.c
@@ -48,6 +48,7 @@
#include "mock_tusb_callback.h"
#include "mock_hid_host.h"
#include "mock_cdc_host.h"
+#include "mock_msc_host.h"
extern usbh_device_info_t usbh_devices[TUSB_CFG_HOST_DEVICE_MAX+1];
extern uint8_t enum_data_buffer[TUSB_CFG_HOST_ENUM_BUFFER_SIZE];
@@ -177,12 +178,31 @@ tusb_error_t control_xfer_stub(uint8_t dev_addr, const tusb_control_request_t *
return TUSB_ERROR_NONE;
}
-tusb_error_t hidh_install_stub(uint8_t dev_addr, tusb_descriptor_interface_t const *descriptor, uint16_t *p_length, int num_call)
+tusb_error_t stub_hidh_open(uint8_t dev_addr, tusb_descriptor_interface_t const *descriptor, uint16_t *p_length, int num_call)
{
*p_length = sizeof(tusb_descriptor_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_descriptor_endpoint_t);
return TUSB_ERROR_NONE;
}
+tusb_error_t stub_msch_open(uint8_t dev_addr, tusb_descriptor_interface_t const *descriptor, uint16_t *p_length, int num_call)
+{
+ *p_length = sizeof(tusb_descriptor_interface_t) + 2*sizeof(tusb_descriptor_endpoint_t);
+ return TUSB_ERROR_NONE;
+}
+
+tusb_error_t stub_cdch_open(uint8_t dev_addr, tusb_descriptor_interface_t const *descriptor, uint16_t *p_length, int num_call)
+{
+ *p_length =
+ //------------- Comm Interface -------------//
+ sizeof(tusb_descriptor_interface_t) + sizeof(cdc_desc_func_header_t) +
+ sizeof(cdc_desc_func_abstract_control_management_t) + sizeof(cdc_desc_func_union_t) +
+ sizeof(tusb_descriptor_endpoint_t) +
+ //------------- Data Interface -------------//
+ sizeof(tusb_descriptor_interface_t) + 2*sizeof(tusb_descriptor_endpoint_t);
+
+ return TUSB_ERROR_NONE;
+}
+
//--------------------------------------------------------------------+
// enumeration
//--------------------------------------------------------------------+
@@ -264,11 +284,6 @@ void test_enum_failed_get_full_config_desc(void)
usbh_enumeration_task(NULL);
}
-void class_install_expect(void)
-{
- hidh_open_subtask_StubWithCallback(hidh_install_stub);
-}
-
void test_enum_parse_config_desc(void)
{
osal_semaphore_wait_StubWithCallback(semaphore_wait_timeout_stub(5));
@@ -295,11 +310,16 @@ void test_enum_set_configure(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);
- class_install_expect();
+
+ // class open TODO more class expect
+ hidh_open_subtask_StubWithCallback(stub_hidh_open);
+ msch_open_subtask_StubWithCallback(stub_msch_open);
+ cdch_open_subtask_StubWithCallback(stub_cdch_open);
tusbh_device_mount_succeed_cb_Expect(1);
usbh_enumeration_task(NULL);
- TEST_ASSERT_EQUAL(TUSB_CLASS_FLAG_HID, usbh_devices[1].flag_supported_class); // TODO change later
+ TEST_ASSERT_EQUAL(TUSB_CLASS_FLAG_HID | TUSB_CLASS_FLAG_MSC | TUSB_CLASS_FLAG_CDC,
+ usbh_devices[1].flag_supported_class); // TODO change later
}
diff --git a/tests/support/descriptor_test.c b/tests/support/descriptor_test.c
index 725baa841..e8daadb91 100644
--- a/tests/support/descriptor_test.c
+++ b/tests/support/descriptor_test.c
@@ -151,7 +151,7 @@ const app_configuration_desc_t desc_configuration =
.bDescriptorType = TUSB_DESC_TYPE_CONFIGURATION,
.wTotalLength = sizeof(app_configuration_desc_t) - 1, // exclude termination
- .bNumInterfaces = 3,
+ .bNumInterfaces = 5,
.bConfigurationValue = 1,
.iConfiguration = 0x00,
@@ -263,5 +263,92 @@ const app_configuration_desc_t desc_configuration =
.bInterval = 1
},
+ //------------- CDC Serial -------------//
+ .cdc_comm_interface =
+ {
+ .bLength = sizeof(tusb_descriptor_interface_t),
+ .bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
+ .bInterfaceNumber = 4,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = TUSB_CLASS_CDC,
+ .bInterfaceSubClass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL,
+ .bInterfaceProtocol = CDC_COMM_PROTOCOL_ATCOMMAND,
+ .iInterface = 0x00
+ },
+
+ .cdc_header =
+ {
+ .bLength = sizeof(cdc_desc_func_header_t),
+ .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
+ .bDescriptorSubType = CDC_FUNC_DESC_HEADER,
+ .bcdCDC = 0x0120
+ },
+
+ .cdc_acm =
+ {
+ .bLength = sizeof(cdc_desc_func_abstract_control_management_t),
+ .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
+ .bDescriptorSubType = CDC_FUNC_DESC_ABSTRACT_CONTROL_MANAGEMENT,
+ .bmCapabilities = { // 0x06
+ .support_line_request = 1,
+ .support_send_break = 1
+ }
+ },
+
+ .cdc_union =
+ {
+ .bLength = sizeof(cdc_desc_func_union_t), // plus number of
+ .bDescriptorType = TUSB_DESC_TYPE_INTERFACE_CLASS_SPECIFIC,
+ .bDescriptorSubType = CDC_FUNC_DESC_UNION,
+ .bControlInterface = 1,
+ .bSubordinateInterface = 2,
+ },
+
+ .cdc_endpoint_notification =
+ {
+ .bLength = sizeof(tusb_descriptor_endpoint_t),
+ .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
+ .bEndpointAddress = 0x84,
+ .bmAttributes = { .xfer = TUSB_XFER_INTERRUPT },
+ .wMaxPacketSize = 8,
+ .bInterval = 0x0a // lowest polling rate
+ },
+
+ //------------- CDC Data Interface -------------//
+ .cdc_data_interface =
+ {
+ .bLength = sizeof(tusb_descriptor_interface_t),
+ .bDescriptorType = TUSB_DESC_TYPE_INTERFACE,
+ .bInterfaceNumber = 5,
+ .bAlternateSetting = 0x00,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = TUSB_CLASS_CDC_DATA,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = 0,
+ .iInterface = 0x00
+ },
+
+ .cdc_endpoint_out =
+ {
+ .bLength = sizeof(tusb_descriptor_endpoint_t),
+ .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
+ .bEndpointAddress = 5,
+ .bmAttributes = { .xfer = TUSB_XFER_BULK },
+ .wMaxPacketSize = 64,
+ .bInterval = 0
+ },
+
+ .cdc_endpoint_in =
+ {
+ .bLength = sizeof(tusb_descriptor_endpoint_t),
+ .bDescriptorType = TUSB_DESC_TYPE_ENDPOINT,
+ .bEndpointAddress = 0x85,
+ .bmAttributes = { .xfer = TUSB_XFER_BULK },
+ .wMaxPacketSize = 64,
+ .bInterval = 0
+ },
+
+ // TODO CDC & RNDIS
.ConfigDescTermination = 0,
};
diff --git a/tests/support/descriptor_test.h b/tests/support/descriptor_test.h
index 39d23e2c1..a452d95ef 100644
--- a/tests/support/descriptor_test.h
+++ b/tests/support/descriptor_test.h
@@ -59,6 +59,7 @@
#include "common/common.h"
#include "class/hid.h"
#include "class/msc.h"
+#include "class/cdc.h"
typedef struct
{
@@ -98,6 +99,20 @@ typedef struct
tusb_descriptor_endpoint_t msc_endpoint_in;
tusb_descriptor_endpoint_t msc_endpoint_out;
+ //------------- CDC Serial -------------//
+ //CDC Control Interface
+ tusb_descriptor_interface_t cdc_comm_interface;
+ cdc_desc_func_header_t cdc_header;
+ cdc_desc_func_abstract_control_management_t cdc_acm;
+ cdc_desc_func_union_t cdc_union;
+ tusb_descriptor_endpoint_t cdc_endpoint_notification;
+
+ //CDC Data Interface
+ tusb_descriptor_interface_t cdc_data_interface;
+ tusb_descriptor_endpoint_t cdc_endpoint_out;
+ tusb_descriptor_endpoint_t cdc_endpoint_in;
+
+
unsigned char ConfigDescTermination;
} app_configuration_desc_t;
diff --git a/tests/support/tusb_config.h b/tests/support/tusb_config.h
index e9c7b92a4..320b32222 100644
--- a/tests/support/tusb_config.h
+++ b/tests/support/tusb_config.h
@@ -74,6 +74,7 @@
//------------- CLASS -------------//
#define TUSB_CFG_HOST_HID_KEYBOARD 1
#define TUSB_CFG_HOST_HID_MOUSE 1
+#define TUSB_CFG_HOST_MSC 1
#define TUSB_CFG_HOST_CDC 1
#define TUSB_CFG_HOST_CDC_RNDIS 1
diff --git a/tinyusb/class/hid_host.c b/tinyusb/class/hid_host.c
index 9018c6123..5dc450fa9 100644
--- a/tinyusb/class/hid_host.c
+++ b/tinyusb/class/hid_host.c
@@ -214,7 +214,7 @@ tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con
OSAL_SUBTASK_BEGIN
-#if 0
+#if 1
//------------- SET IDLE request -------------//
// TODO this request can be stalled by device (indicate not supported),
// until we have clear stall handler, temporarily disable it.
@@ -224,7 +224,9 @@ tusb_error_t hidh_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con
0, NULL ),
error
);
+#endif
+#if 0
//------------- Get Report Descriptor TODO HID parser -------------//
if ( p_desc_hid->bNumDescriptors )
{
diff --git a/tinyusb/class/msc_host.c b/tinyusb/class/msc_host.c
index 00aebeba9..1e11a4b85 100644
--- a/tinyusb/class/msc_host.c
+++ b/tinyusb/class/msc_host.c
@@ -51,26 +51,10 @@
//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF
//--------------------------------------------------------------------+
-typedef struct {
- pipe_handle_t bulk_in, bulk_out;
- uint8_t interface_number;
+STATIC_VAR msch_interface_t msch_data[TUSB_CFG_HOST_DEVICE_MAX] TUSB_CFG_ATTR_USBRAM;
- uint8_t max_lun;
- uint16_t block_size;
- uint32_t last_lba; // last logical block address
-
- uint8_t vendor_id[8];
- uint8_t product_id[16];
-
- msc_cmd_block_wrapper_t cbw;
- msc_cmd_status_wrapper_t csw;
- ATTR_ALIGNED(4) uint8_t buffer[100];
-}msch_interface_t;
-
-STATIC_VAR msch_interface_t msch_data[TUSB_CFG_HOST_DEVICE_MAX] TUSB_CFG_ATTR_USBRAM; // TODO to be static
-
-// TODO rename this
-STATIC_VAR uint8_t msch_buffer[10] TUSB_CFG_ATTR_USBRAM;
+// 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;
//--------------------------------------------------------------------+
// INTERNAL OBJECT & FUNCTION DECLARATION
@@ -110,7 +94,7 @@ tusb_error_t tusbh_msc_get_capacity(uint8_t dev_addr, uint32_t* p_last_lba, uint
//--------------------------------------------------------------------+
// CLASS-USBH API (don't require to verify parameters)
//--------------------------------------------------------------------+
-static tusb_error_t scsi_command_send(msch_interface_t * p_msch, scsi_cmd_type_t cmd_code, uint8_t lun)
+static tusb_error_t scsi_command_send(msch_interface_t * p_msch, scsi_cmd_type_t cmd_code, uint8_t lun, uint8_t* p_data)
{
p_msch->cbw.signature = 0x43425355;
p_msch->cbw.tag = 0xCAFECAFE;
@@ -175,7 +159,7 @@ static tusb_error_t scsi_command_send(msch_interface_t * p_msch, scsi_cmd_type_t
}
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_out, (uint8_t*) &p_msch->cbw, sizeof(msc_cmd_block_wrapper_t), false) );
- ASSERT_STATUS( hcd_pipe_queue_xfer(p_msch->bulk_in , p_msch->buffer, p_msch->cbw.xfer_bytes) );
+ ASSERT_STATUS( hcd_pipe_queue_xfer(p_msch->bulk_in , p_data, p_msch->cbw.xfer_bytes) );
ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_in , &p_msch->csw, sizeof(msc_cmd_status_wrapper_t), true) );
}
@@ -240,28 +224,24 @@ tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con
// while( !hcd_pipe_is_idle(msch_data[dev_addr-1].bulk_in) )
//------------- SCSI Inquiry -------------//
- scsi_command_send(&msch_data[dev_addr-1], SCSI_CMD_INQUIRY, 0);
+ scsi_command_send(&msch_data[dev_addr-1], SCSI_CMD_INQUIRY, 0, msch_buffer);
osal_task_delay(2);
- memcpy(msch_data[dev_addr-1].vendor_id,
- ((scsi_inquiry_data_t*)msch_data[dev_addr-1].buffer)->vendor_id,
- 8);
- memcpy(msch_data[dev_addr-1].product_id,
- ((scsi_inquiry_data_t*)msch_data[dev_addr-1].buffer)->product_id,
- 16);
+ 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);
+ 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);
+ scsi_command_send(&msch_data[dev_addr-1], SCSI_CMD_READ_CAPACITY_10, 0, msch_buffer);
osal_task_delay(2);
- msch_data[dev_addr-1].last_lba = __be2le( ((scsi_read_capacity10_data_t*)msch_data[dev_addr-1].buffer)->last_lba );
- msch_data[dev_addr-1].block_size = (uint16_t) __be2le( ((scsi_read_capacity10_data_t*)msch_data[dev_addr-1].buffer)->block_size );
+ 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 );
tusbh_msc_mounted_cb(dev_addr);
diff --git a/tinyusb/class/msc_host.h b/tinyusb/class/msc_host.h
index 324dad984..65265ddb9 100644
--- a/tinyusb/class/msc_host.h
+++ b/tinyusb/class/msc_host.h
@@ -76,6 +76,8 @@ tusb_error_t tusbh_msc_write10(uint8_t dev_addr, void const * p_data, uint32_t
//------------- Application Callback -------------//
void tusbh_msc_mounted_cb(uint8_t dev_addr);
+void tusbh_msc_unmounted_isr(uint8_t dev_addr);
+void tusbh_msc_isr(uint8_t dev_addr, tusb_event_t event);
//--------------------------------------------------------------------+
@@ -83,6 +85,21 @@ void tusbh_msc_mounted_cb(uint8_t dev_addr);
//--------------------------------------------------------------------+
#ifdef _TINY_USB_SOURCE_FILE_
+typedef struct {
+ pipe_handle_t bulk_in, bulk_out;
+ uint8_t interface_number;
+
+ uint8_t max_lun;
+ uint16_t block_size;
+ uint32_t last_lba; // last logical block address
+
+ uint8_t vendor_id[8];
+ uint8_t product_id[16];
+
+ msc_cmd_block_wrapper_t cbw;
+ msc_cmd_status_wrapper_t csw;
+}msch_interface_t;
+
void msch_init(void);
tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *p_interface_desc, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT;
void msch_isr(pipe_handle_t pipe_hdl, tusb_event_t event, uint32_t xferred_bytes);
diff --git a/tinyusb/common/compiler/compiler.h b/tinyusb/common/compiler/compiler.h
index e1f06b307..683237b54 100644
--- a/tinyusb/common/compiler/compiler.h
+++ b/tinyusb/common/compiler/compiler.h
@@ -52,12 +52,7 @@
#ifndef _TUSB_COMPILER_H_
#define _TUSB_COMPILER_H_
-#ifdef _TEST_
- #define ATTR_ALWAYS_INLINE
- #define STATIC_
- #define STATIC_VAR
- #define INLINE_
-#else
+#ifndef _TEST_
#define STATIC_ static
#define INLINE_ inline
@@ -67,9 +62,14 @@
#else
#define STATIC_VAR static
#endif
+ #define ATTR_TEST_WEAK
+#else
+ #define ATTR_ALWAYS_INLINE
+ #define STATIC_
+ #define STATIC_VAR
+ #define INLINE_
#endif
-// TODO refractor ATTR_PACKED(x)
#if defined(__GNUC__)
#include "compiler_gcc.h"
#elif defined __ICCARM__ // IAR compiler
diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c
index b2948e0db..40c59616e 100644
--- a/tinyusb/host/ehci/ehci.c
+++ b/tinyusb/host/ehci/ehci.c
@@ -446,6 +446,7 @@ tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl)
ehci_qhd_t *p_qhd = qhd_get_from_pipe_handle( pipe_hdl );
// async list needs async advance handshake to make sure host controller has released cached data
+ // non-control does not use async advance, it will eventually free by control pipe close
// period list queue element is guarantee to be free in the next frame (1 ms)
p_qhd->is_removing = 1; // TODO redundant, only apply to control queue head
@@ -620,29 +621,47 @@ static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd)
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
{ // current qhd has error in transaction
- uint16_t total_xferred_bytes;
tusb_xfer_type_t const xfer_type = qhd_get_xfer_type(p_qhd);
tusb_event_t error_event;
- // TODO allow stall with control pipe
// 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;
p_qhd->total_xferred_bytes += p_qhd->p_qtd_list_head->expected_bytes - p_qhd->p_qtd_list_head->total_bytes;
- hal_debugger_breakpoint();
+ // TODO skip unplugged device
+ if ( TUSB_EVENT_XFER_ERROR == error_event ) hal_debugger_breakpoint();
p_qhd->p_qtd_list_head->used = 0; // free QTD
qtd_remove_1st_from_qhd(p_qhd);
- // subtract setup size if it is control xfer
- total_xferred_bytes = p_qhd->total_xferred_bytes - (xfer_type == TUSB_XFER_CONTROL ? min8_of(8, p_qhd->total_xferred_bytes) : 0);
+ if ( TUSB_XFER_CONTROL == xfer_type )
+ {
+ p_qhd->total_xferred_bytes -= min8_of(8, p_qhd->total_xferred_bytes); // subtract setup size
+
+ // control cannot be halted --> clear all qtd list
+ p_qhd->p_qtd_list_head = NULL;
+ p_qhd->p_qtd_list_tail = NULL;
+
+ p_qhd->qtd_overlay.next.terminate = 1;
+ p_qhd->qtd_overlay.alternate.terminate = 1;
+ p_qhd->qtd_overlay.halted = 0;
+
+ #if 0 // no need to mark control qtds as not used
+ ehci_qtd_t *p_setup = get_control_qtds(dev_addr);
+ ehci_qtd_t *p_data = p_setup + 1;
+ ehci_qtd_t *p_status = p_setup + 2;
+
+ p_setup->used = p_data->used = p_status = 0;
+ #endif
+ }
// call USBH callback
usbh_xfer_isr( qhd_create_pipe_handle(p_qhd, xfer_type),
p_qhd->class_code, error_event,
- total_xferred_bytes);
+ p_qhd->total_xferred_bytes);
+
p_qhd->total_xferred_bytes = 0;
}
}