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; } }