From f8f398a6813567306acd2e9dcfae199c3ecbad3a Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 20 Sep 2013 23:53:48 +0700 Subject: [PATCH] start to add msc host, fix dangerous problem with unstable device when plugged --> 200 ms delay. 50ms delay after each port reset --- .../boards/embedded_artists/board_ea4357.c | 6 +- .../boards/embedded_artists/board_ea4357.h | 4 +- demos/host/host_os_none/host_os_none.uvopt | 161 +++++++++++------- demos/host/host_os_none/host_os_none.uvproj | 20 +++ demos/host/src/cdc_serial_app.c | 9 + demos/host/src/keyboard_app.c | 9 + demos/host/src/main.c | 19 +-- demos/host/src/mouse_app.c | 9 + demos/host/src/msc_app.c | 90 ++++++++++ demos/host/src/rndis_app.c | 15 ++ demos/host/src/tusb_config.h | 2 +- tinyusb/class/cdc_host.c | 4 +- tinyusb/class/hid_host.c | 8 +- tinyusb/class/msc.h | 5 + tinyusb/class/msc_host.c | 65 ++++++- tinyusb/class/msc_host.h | 19 ++- tinyusb/common/errors.h | 3 +- tinyusb/host/ehci/ehci.c | 1 + tinyusb/host/hcd.h | 2 +- tinyusb/host/usbh.c | 12 +- 20 files changed, 358 insertions(+), 105 deletions(-) create mode 100644 demos/host/src/msc_app.c diff --git a/demos/bsp/boards/embedded_artists/board_ea4357.c b/demos/bsp/boards/embedded_artists/board_ea4357.c index 92d2bc49d..9e88c5d6b 100644 --- a/demos/bsp/boards/embedded_artists/board_ea4357.c +++ b/demos/bsp/boards/embedded_artists/board_ea4357.c @@ -62,9 +62,9 @@ void board_init(void) // TODO Device only USB0 // 1.5Kohm pull-up resistor is needed on the USB DP data signal. GPIO28 (base), P9_5 (LPC4357) controls - scu_pinmux(0x9, 5, MD_PUP|MD_EZI|MD_ZI, FUNC4); // GPIO5[18] - GPIO_SetDir(5, BIT_(18), 1); // output - GPIO_ClearValue(5, BIT_(18)); +// scu_pinmux(0x9, 5, MD_PUP|MD_EZI|MD_ZI, FUNC4); // GPIO5[18] +// GPIO_SetDir(5, BIT_(18), 1); // output +// GPIO_ClearValue(5, BIT_(18)); //------------- I2C (required by LED) -------------// diff --git a/demos/bsp/boards/embedded_artists/board_ea4357.h b/demos/bsp/boards/embedded_artists/board_ea4357.h index 138e6e199..0cef17358 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 +//#define CFG_PRINTF_TARGET PRINTF_TARGET_SWO +#define CFG_PRINTF_TARGET PRINTF_TARGET_UART /*========================================================================= 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 45db11ebb..47780250f 100644 --- a/demos/host/host_os_none/host_os_none.uvopt +++ b/demos/host/host_os_none/host_os_none.uvopt @@ -165,12 +165,17 @@ 1 usbh_devices + + 1 + 1 + msch_data + 0 1 1 - 1 + 0 0 0 0 @@ -184,7 +189,7 @@ 0 0 0 - 1 + 0 0 1 0 @@ -197,6 +202,12 @@ + + + System Viewer\USB0 + 35905 + + @@ -392,10 +403,10 @@ 1 0 0 - 54 + 43 0 - 171 - 191 + 164 + 171 0 ..\src\main.c main.c @@ -424,10 +435,10 @@ 1 0 0 - 20 + 0 0 - 120 - 129 + 1 + 1 0 ..\src\keyboard_app.c keyboard_app.c @@ -442,8 +453,8 @@ 0 0 0 - 122 - 131 + 1 + 1 0 ..\src\mouse_app.c mouse_app.c @@ -466,6 +477,22 @@ 0 0 + + 1 + 6 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + ..\src\msc_app.c + msc_app.c + 0 + 0 + @@ -476,7 +503,7 @@ 0 2 - 6 + 7 1 0 0 @@ -492,13 +519,13 @@ 2 - 7 + 8 1 0 0 2 0 - 139 + 140 146 0 ..\..\bsp\boards\embedded_artists\board_ea4357.c @@ -508,13 +535,13 @@ 2 - 8 + 9 1 0 0 1 0 - 101 + 102 106 0 ..\..\bsp\boards\printf_retarget.c @@ -524,7 +551,7 @@ 2 - 9 + 10 1 0 0 @@ -540,7 +567,7 @@ 2 - 10 + 11 1 0 0 @@ -556,7 +583,7 @@ 2 - 11 + 12 1 0 0 @@ -572,7 +599,7 @@ 2 - 12 + 13 1 0 0 @@ -588,7 +615,7 @@ 2 - 13 + 14 1 0 0 @@ -604,7 +631,7 @@ 2 - 14 + 15 1 0 0 @@ -620,7 +647,7 @@ 2 - 15 + 16 1 0 0 @@ -638,20 +665,20 @@ tinyusb - 0 + 1 0 0 0 3 - 16 + 17 1 0 0 0 0 57 - 76 + 69 0 ..\..\..\tinyusb\tusb.c tusb.c @@ -660,7 +687,7 @@ 3 - 17 + 18 1 0 0 @@ -676,7 +703,7 @@ 3 - 18 + 19 1 0 0 @@ -692,7 +719,7 @@ 3 - 19 + 20 1 0 0 @@ -708,14 +735,14 @@ 3 - 20 + 21 1 0 0 0 0 - 1 - 1 + 370 + 375 0 ..\..\..\tinyusb\host\usbh.c usbh.c @@ -724,14 +751,14 @@ 3 - 21 + 22 1 0 0 - 47 + 25 0 - 4 - 13 + 141 + 147 0 ..\..\..\tinyusb\host\ehci\ehci.c ehci.c @@ -740,7 +767,7 @@ 3 - 22 + 23 1 0 0 @@ -756,7 +783,7 @@ 3 - 23 + 24 1 0 0 @@ -772,14 +799,14 @@ 3 - 24 + 25 1 0 0 - 8 + 7 0 - 68 - 77 + 101 + 112 0 ..\..\..\tinyusb\hal\hal_lpc43xx.c hal_lpc43xx.c @@ -788,7 +815,7 @@ 3 - 25 + 26 1 0 0 @@ -804,7 +831,7 @@ 3 - 26 + 27 1 0 0 @@ -820,7 +847,7 @@ 3 - 27 + 28 1 0 0 @@ -836,14 +863,14 @@ 3 - 28 + 29 1 0 0 - 28 + 0 0 - 23 - 32 + 1 + 1 0 ..\..\..\tinyusb\class\cdc_host.c cdc_host.c @@ -852,7 +879,7 @@ 3 - 29 + 30 1 0 0 @@ -868,7 +895,7 @@ 3 - 30 + 31 1 0 0 @@ -882,6 +909,22 @@ 0 0 + + 3 + 32 + 1 + 0 + 0 + 15 + 0 + 86 + 90 + 0 + ..\..\..\tinyusb\class\msc_host.c + msc_host.c + 0 + 0 + @@ -892,7 +935,7 @@ 0 4 - 31 + 33 1 0 0 @@ -908,7 +951,7 @@ 4 - 32 + 34 1 0 0 @@ -924,7 +967,7 @@ 4 - 33 + 35 1 0 0 @@ -940,7 +983,7 @@ 4 - 34 + 36 1 0 0 @@ -956,7 +999,7 @@ 4 - 35 + 37 1 0 0 @@ -972,7 +1015,7 @@ 4 - 36 + 38 1 0 0 @@ -996,14 +1039,14 @@ 0 5 - 37 + 39 2 0 0 0 0 - 146 - 151 + 145 + 146 0 ..\..\bsp\lpc43xx\startup_keil\startup_LPC43xx.s startup_LPC43xx.s diff --git a/demos/host/host_os_none/host_os_none.uvproj b/demos/host/host_os_none/host_os_none.uvproj index 1de4faabd..644f41bf9 100644 --- a/demos/host/host_os_none/host_os_none.uvproj +++ b/demos/host/host_os_none/host_os_none.uvproj @@ -416,6 +416,11 @@ 1 ..\src\rndis_app.c + + msc_app.c + 1 + ..\src\msc_app.c + @@ -551,6 +556,11 @@ 1 ..\..\..\tinyusb\class\hid_host.c + + msc_host.c + 1 + ..\..\..\tinyusb\class\msc_host.c + @@ -1010,6 +1020,11 @@ 1 ..\src\rndis_app.c + + msc_app.c + 1 + ..\src\msc_app.c + @@ -1185,6 +1200,11 @@ 1 ..\..\..\tinyusb\class\hid_host.c + + msc_host.c + 1 + ..\..\..\tinyusb\class\msc_host.c + diff --git a/demos/host/src/cdc_serial_app.c b/demos/host/src/cdc_serial_app.c index e44cfd924..a6616964b 100644 --- a/demos/host/src/cdc_serial_app.c +++ b/demos/host/src/cdc_serial_app.c @@ -135,5 +135,14 @@ OSAL_TASK_FUNCTION( cdc_serial_app_task ) (void* p_task_para) OSAL_TASK_LOOP_END } +#else + +// dummy implementation to remove #ifdef in main.c +void cdc_serial_app_init(void) { } +OSAL_TASK_FUNCTION( cdc_serial_app_task ) (void* p_task_para) +{ + OSAL_TASK_LOOP_BEGIN + OSAL_TASK_LOOP_END +} #endif diff --git a/demos/host/src/keyboard_app.c b/demos/host/src/keyboard_app.c index 404a27c41..b0f92a2c7 100644 --- a/demos/host/src/keyboard_app.c +++ b/demos/host/src/keyboard_app.c @@ -178,4 +178,13 @@ static inline uint8_t keycode_to_ascii(uint8_t modifier, uint8_t keycode) hid_keycode_to_ascii_tbl [modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT) ? 1 : 0] [keycode]; } +#else + +// dummy implementation to remove #ifdef in main.c +void keyboard_app_init(void) { } +OSAL_TASK_FUNCTION( keyboard_app_task ) (void* p_task_para) +{ + OSAL_TASK_LOOP_BEGIN + OSAL_TASK_LOOP_END +} #endif diff --git a/demos/host/src/main.c b/demos/host/src/main.c index ca26e633f..66df55d7a 100644 --- a/demos/host/src/main.c +++ b/demos/host/src/main.c @@ -55,7 +55,7 @@ #include "cdc_serial_app.h" #include "rndis_app.h" -#if defined(__CODE_RED) +#if defined(__CODE_RED) // TODO to be removed #include #include // Variable to store CRP value in. Will be placed automatically @@ -104,10 +104,13 @@ void os_none_start_scheduler(void) while (1) { tusb_task_runner(); + led_blinking_task(NULL); + keyboard_app_task(NULL); mouse_app_task(NULL); + msc_app_task(NULL); cdc_serial_app_task(NULL); - led_blinking_task(NULL); + rndis_app_task(NULL); } } #endif @@ -123,21 +126,11 @@ int main(void) //------------- application task init -------------// (void) osal_task_create( OSAL_TASK_REF(led_blinking_task) ); -#if TUSB_CFG_HOST_HID_KEYBOARD keyboard_app_init(); -#endif - -#if TUSB_CFG_HOST_HID_MOUSE mouse_app_init(); -#endif - -#if TUSB_CFG_HOST_CDC + msc_app_init(); cdc_serial_app_init(); - - #if TUSB_CFG_HOST_CDC_RNDIS rndis_app_init(); - #endif -#endif //------------- start OS scheduler (never return) -------------// #if TUSB_CFG_OS == TUSB_OS_FREERTOS diff --git a/demos/host/src/mouse_app.c b/demos/host/src/mouse_app.c index 3469fc4ab..32596e9e2 100644 --- a/demos/host/src/mouse_app.c +++ b/demos/host/src/mouse_app.c @@ -156,5 +156,14 @@ static inline void process_mouse_report(tusb_mouse_report_t const * p_report) } +#else + +// dummy implementation to remove #ifdef in main.c +void mouse_app_init(void) { } +OSAL_TASK_FUNCTION( mouse_app_task ) (void* p_task_para) +{ + OSAL_TASK_LOOP_BEGIN + OSAL_TASK_LOOP_END +} #endif diff --git a/demos/host/src/msc_app.c b/demos/host/src/msc_app.c new file mode 100644 index 000000000..54de0d0cf --- /dev/null +++ b/demos/host/src/msc_app.c @@ -0,0 +1,90 @@ +/**************************************************************************/ +/*! + @file msc_app.c + @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. +*/ +/**************************************************************************/ + +//--------------------------------------------------------------------+ +// INCLUDE +//--------------------------------------------------------------------+ +#include "mouse_app.h" + +#if TUSB_CFG_OS != TUSB_OS_NONE +#include "app_os_prio.h" +#endif + +#if TUSB_CFG_HOST_MSC + +//--------------------------------------------------------------------+ +// MACRO CONSTANT TYPEDEF +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// INTERNAL OBJECT & FUNCTION DECLARATION +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// tinyusb callback (ISR context) +//--------------------------------------------------------------------+ +void tusbh_msc_mounted_cb(uint8_t dev_addr) +{ + printf("an msc device is mounted\n"); +} + +//--------------------------------------------------------------------+ +// IMPLEMENTATION +//--------------------------------------------------------------------+ +void msc_app_init(void) +{ + +} + +//------------- main task -------------// +OSAL_TASK_FUNCTION( msc_app_task ) (void* p_task_para) +{ + +} + +#else +// dummy implementation to remove #ifdef in main.c +void msc_app_init(void) { } +OSAL_TASK_FUNCTION( msc_app_task ) (void* p_task_para) +{ + OSAL_TASK_LOOP_BEGIN + OSAL_TASK_LOOP_END +} + + +#endif diff --git a/demos/host/src/rndis_app.c b/demos/host/src/rndis_app.c index cb9c9ba0d..d0027ea97 100644 --- a/demos/host/src/rndis_app.c +++ b/demos/host/src/rndis_app.c @@ -69,5 +69,20 @@ void rndis_app_init(void) } +OSAL_TASK_FUNCTION( rndis_app_task ) (void* p_task_para) +{ + OSAL_TASK_LOOP_BEGIN + OSAL_TASK_LOOP_END +} + +#else + +// dummy implementation to remove #ifdef in main.c +void rndis_app_init(void) { } +OSAL_TASK_FUNCTION( rndis_app_task ) (void* p_task_para) +{ + OSAL_TASK_LOOP_BEGIN + OSAL_TASK_LOOP_END +} #endif diff --git a/demos/host/src/tusb_config.h b/demos/host/src/tusb_config.h index 215a77cbc..30891fcbb 100644 --- a/demos/host/src/tusb_config.h +++ b/demos/host/src/tusb_config.h @@ -76,7 +76,7 @@ #define TUSB_CFG_HOST_HID_KEYBOARD 1 #define TUSB_CFG_HOST_HID_MOUSE 1 #define TUSB_CFG_HOST_HID_GENERIC 0 -#define TUSB_CFG_HOST_MSC 0 +#define TUSB_CFG_HOST_MSC 1 #define TUSB_CFG_HOST_CDC 1 #define TUSB_CFG_HOST_CDC_RNDIS 1 diff --git a/tinyusb/class/cdc_host.c b/tinyusb/class/cdc_host.c index 8f4bc7e21..c90e84dbb 100644 --- a/tinyusb/class/cdc_host.c +++ b/tinyusb/class/cdc_host.c @@ -56,7 +56,7 @@ //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -/*STATIC_*/ cdch_data_t cdch_data[TUSB_CFG_HOST_DEVICE_MAX]; +/*STATIC_*/ cdch_data_t cdch_data[TUSB_CFG_HOST_DEVICE_MAX]; // TODO to be static STATIC_ INLINE_ bool tusbh_cdc_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; STATIC_ INLINE_ bool tusbh_cdc_is_mounted(uint8_t dev_addr) @@ -193,7 +193,7 @@ tusb_error_t cdch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con for(uint32_t i=0; i<2; i++) { 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_CDCH_DESCRIPTOR_CORRUPTED); + ASSERT_INT(TUSB_DESC_TYPE_ENDPOINT, p_endpoint->bDescriptorType, 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/hid_host.c b/tinyusb/class/hid_host.c index 60e0ab6d3..e3d74fa12 100644 --- a/tinyusb/class/hid_host.c +++ b/tinyusb/class/hid_host.c @@ -83,12 +83,8 @@ static inline tusb_error_t hidh_interface_open(uint8_t dev_addr, uint8_t interfa static inline void hidh_interface_close(uint8_t dev_addr, hidh_interface_info_t *p_hid) ATTR_ALWAYS_INLINE; static inline void hidh_interface_close(uint8_t dev_addr, hidh_interface_info_t *p_hid) { - pipe_handle_t pipe_hdl = p_hid->pipe_hdl; - if ( pipehandle_is_valid(pipe_hdl) ) - { - memclr_(p_hid, sizeof(hidh_interface_info_t)); - ASSERT_INT( TUSB_ERROR_NONE, hcd_pipe_close(pipe_hdl), VOID_RETURN ); - } + (void) hcd_pipe_close(p_hid->pipe_hdl); + memclr_(p_hid, sizeof(hidh_interface_info_t)); } // called from public API need to validate parameters diff --git a/tinyusb/class/msc.h b/tinyusb/class/msc.h index 53e2e93df..efa137a2b 100644 --- a/tinyusb/class/msc.h +++ b/tinyusb/class/msc.h @@ -71,6 +71,11 @@ enum { MSC_PROTOCOL_BOT = 0x50 }; +enum { + MSC_REQUEST_GET_MAX_LUN = 254, + MSC_REQUEST_RESET = 255 +}; + //--------------------------------------------------------------------+ // SCSI Primary Command (SPC-4) diff --git a/tinyusb/class/msc_host.c b/tinyusb/class/msc_host.c index 5d0630813..760bc34f5 100644 --- a/tinyusb/class/msc_host.c +++ b/tinyusb/class/msc_host.c @@ -51,6 +51,16 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +typedef struct { + pipe_handle_t bulk_in, bulk_out; + uint8_t interface_number; + uint8_t max_lun; +}msch_interface_t; + +/*STATIC_*/ msch_interface_t msch_data[TUSB_CFG_HOST_DEVICE_MAX]; // TODO to be static + +// TODO rename this +STATIC_ uint8_t msch_buffer[10] TUSB_CFG_ATTR_USBRAM; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION @@ -59,13 +69,61 @@ //--------------------------------------------------------------------+ // IMPLEMENTATION //--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// CLASS-USBH API (don't require to verify parameters) +//--------------------------------------------------------------------+ void msch_init(void) { - + memclr_(msch_data, sizeof(msch_interface_t)*TUSB_CFG_HOST_DEVICE_MAX); } -tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *descriptor, uint16_t *p_length) +tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *p_interface_desc, uint16_t *p_length) { + tusb_error_t error; + + OSAL_SUBTASK_BEGIN + + if (! ( MSC_SUBCLASS_SCSI == p_interface_desc->bInterfaceSubClass && + MSC_PROTOCOL_BOT == p_interface_desc->bInterfaceProtocol ) ) + { + return TUSB_ERROR_MSCH_UNSUPPORTED_PROTOCOL; + } + + //------------- Open Data Pipe -------------// + tusb_descriptor_endpoint_t const *p_endpoint = (tusb_descriptor_endpoint_t const *) descriptor_next( p_interface_desc ); + for(uint32_t i=0; i<2; i++) + { + ASSERT_INT(TUSB_DESC_TYPE_ENDPOINT, p_endpoint->bDescriptorType, 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; + + (*p_pipe_hdl) = hcd_pipe_open(dev_addr, p_endpoint, TUSB_CLASS_MSC); + ASSERT ( pipehandle_is_valid(*p_pipe_hdl), TUSB_ERROR_HCD_OPEN_PIPE_FAILED ); + + p_endpoint = (tusb_descriptor_endpoint_t const *) descriptor_next( p_endpoint ); + } + + msch_data[dev_addr-1].interface_number = p_interface_desc->bInterfaceNumber; + (*p_length) += sizeof(tusb_descriptor_interface_t) + 2*sizeof(tusb_descriptor_endpoint_t); + + 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), + MSC_REQUEST_GET_MAX_LUN, 0, msch_data[dev_addr-1].interface_number, + 1, msch_buffer ), + error + ); + + if(TUSB_ERROR_NONE == error /* TODO STALL means zero */) + { + msch_data[dev_addr-1].max_lun = msch_buffer[0]; + + tusbh_msc_mounted_cb(dev_addr); + } + + OSAL_SUBTASK_END + return TUSB_ERROR_NONE; } @@ -76,7 +134,10 @@ void msch_isr(pipe_handle_t pipe_hdl, tusb_event_t event) void msch_close(uint8_t dev_addr) { + (void) hcd_pipe_close(msch_data[dev_addr-1].bulk_in); + (void) hcd_pipe_close(msch_data[dev_addr-1].bulk_out); + memclr_(&msch_data[dev_addr-1], sizeof(msch_interface_t)); } diff --git a/tinyusb/class/msc_host.h b/tinyusb/class/msc_host.h index 5d73fb6a6..8f90d8923 100644 --- a/tinyusb/class/msc_host.h +++ b/tinyusb/class/msc_host.h @@ -58,14 +58,17 @@ //--------------------------------------------------------------------+ // MASS STORAGE Application API //--------------------------------------------------------------------+ -bool tusbh_msc_scsi_is_supported(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT; -tusb_interface_status_t tusbh_msc_scsi_status(uint8_t dev_addr, uint8_t instance_num) ATTR_WARN_UNUSED_RESULT; +bool tusbh_msc_is_supported(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT; +tusb_interface_status_t tusbh_msc_status(uint8_t dev_addr, uint8_t instance_num) ATTR_WARN_UNUSED_RESULT; + +tusb_error_t tusbh_msc_inquiry(uint8_t dev_addr, uint8_t instance_num, msc_scsi_inquiry_t * p_inquiry_data) ATTR_WARN_UNUSED_RESULT; +tusb_error_t tusbh_msc_test_unit_ready(uint8_t dev_addr, uint8_t instance_num) ATTR_WARN_UNUSED_RESULT; +tusb_error_t tusbh_msc_read_capacity10(uint8_t dev_addr, uint8_t instance_num, msc_scsi_read_capacity10_t * p_buffer) ATTR_WARN_UNUSED_RESULT; +tusb_error_t tusbh_msc_read10(uint8_t dev_addr, uint8_t instance_num, void * p_buffer, uint32_t length) ATTR_WARN_UNUSED_RESULT; +tusb_error_t tusbh_msc_write10(uint8_t dev_addr, uint8_t instance_num, void const * p_data, uint32_t length) ATTR_WARN_UNUSED_RESULT; +//------------- Application Callback -------------// +void tusbh_msc_mounted_cb(uint8_t dev_addr); -tusb_error_t tusbh_msc_scsi_inquiry(uint8_t dev_addr, uint8_t instance_num, msc_scsi_inquiry_t * p_inquiry_data) ATTR_WARN_UNUSED_RESULT; -tusb_error_t tusbh_msc_scsi_test_unit_ready(uint8_t dev_addr, uint8_t instance_num) ATTR_WARN_UNUSED_RESULT; -tusb_error_t tusbh_msc_scsi_read_capacity10(uint8_t dev_addr, uint8_t instance_num, msc_scsi_read_capacity10_t * p_buffer) ATTR_WARN_UNUSED_RESULT; -tusb_error_t tusbh_msc_scsi_read10(uint8_t dev_addr, uint8_t instance_num, void * p_buffer, uint32_t length) ATTR_WARN_UNUSED_RESULT; -tusb_error_t tusbh_msc_scsi_write10(uint8_t dev_addr, uint8_t instance_num, void const * p_data, uint32_t length) ATTR_WARN_UNUSED_RESULT; //--------------------------------------------------------------------+ // USBH-CLASS DRIVER API @@ -73,7 +76,7 @@ tusb_error_t tusbh_msc_scsi_write10(uint8_t dev_addr, uint8_t instance_num, voi #ifdef _TINY_USB_SOURCE_FILE_ void msch_init(void); -tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t const *descriptor, uint16_t *p_length) ATTR_WARN_UNUSED_RESULT; +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); void msch_close(uint8_t dev_addr); #endif diff --git a/tinyusb/common/errors.h b/tinyusb/common/errors.h index 61ac3998d..fae65a1d3 100644 --- a/tinyusb/common/errors.h +++ b/tinyusb/common/errors.h @@ -68,6 +68,7 @@ ENTRY(TUSB_ERROR_HCD_OPEN_PIPE_FAILED )\ 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_OSAL_TIMEOUT )\ ENTRY(TUSB_ERROR_OSAL_WAITING ) /* only used by OSAL_NONE in the subtask */ \ ENTRY(TUSB_ERROR_OSAL_TASK_FAILED )\ @@ -80,10 +81,10 @@ ENTRY(TUSB_ERROR_HIDD_DESCRIPTOR_INTERFACE )\ ENTRY(TUSB_ERROR_HIDH_NOT_SUPPORTED_PROTOCOL )\ ENTRY(TUSB_ERROR_HIDH_NOT_SUPPORTED_SUBCLASS )\ - ENTRY(TUSB_ERROR_CDCH_DESCRIPTOR_CORRUPTED )\ ENTRY(TUSB_ERROR_CDCH_UNSUPPORTED_SUBCLASS )\ ENTRY(TUSB_ERROR_CDCH_UNSUPPORTED_PROTOCOL )\ ENTRY(TUSB_ERROR_CDCH_DEVICE_NOT_MOUNTED )\ + ENTRY(TUSB_ERROR_MSCH_UNSUPPORTED_PROTOCOL )\ ENTRY(TUSB_ERROR_NOT_SUPPORTED_YET )\ ENTRY(TUSB_ERROR_FAILED )\ diff --git a/tinyusb/host/ehci/ehci.c b/tinyusb/host/ehci/ehci.c index 4bc69a51b..4d1a2ebd9 100644 --- a/tinyusb/host/ehci/ehci.c +++ b/tinyusb/host/ehci/ehci.c @@ -613,6 +613,7 @@ static void qhd_xfer_error_isr(ehci_qhd_t * p_qhd) 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; diff --git a/tinyusb/host/hcd.h b/tinyusb/host/hcd.h index bb6b40455..b37378ac7 100644 --- a/tinyusb/host/hcd.h +++ b/tinyusb/host/hcd.h @@ -96,7 +96,7 @@ tusb_error_t hcd_pipe_control_close(uint8_t dev_addr) ATTR_WARN_UNUSED_RESULT; pipe_handle_t hcd_pipe_open(uint8_t dev_addr, tusb_descriptor_endpoint_t const * endpoint_desc, uint8_t class_code) ATTR_WARN_UNUSED_RESULT; 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; +tusb_error_t hcd_pipe_close(pipe_handle_t pipe_hdl) /*ATTR_WARN_UNUSED_RESULT*/; bool hcd_pipe_is_idle(pipe_handle_t pipe_hdl); #if 0 diff --git a/tinyusb/host/usbh.c b/tinyusb/host/usbh.c index 3b9af5801..e95012f01 100644 --- a/tinyusb/host/usbh.c +++ b/tinyusb/host/usbh.c @@ -345,17 +345,15 @@ tusb_error_t enumeration_body_subtask(void) usbh_devices[0].hub_addr = enum_entry.hub_addr; usbh_devices[0].hub_port = enum_entry.hub_port; + osal_task_delay(200); // wait for device is stable + hcd_port_reset( usbh_devices[0].core_id ); // port must be reset to have correct speed operation + osal_task_delay(50); // reset is recommended to last 50 ms usbh_devices[0].speed = hcd_port_speed_get( usbh_devices[0].core_id ); SUBTASK_ASSERT_STATUS( usbh_pipe_control_open(0, 8) ); usbh_devices[0].state = TUSB_DEVICE_STATE_ADDRESSED; -#ifndef _TEST_ - // TODO hack delay 20 ms for slow device (use retry on the 1st xfer instead later) - osal_task_delay(50); -#endif - //------------- Get first 8 bytes of device descriptor to get Control Endpoint Size -------------// OSAL_SUBTASK_INVOKED_AND_WAIT( usbh_control_xfer_subtask( 0, bm_request_type(TUSB_DIR_DEV_TO_HOST, TUSB_REQUEST_TYPE_STANDARD, TUSB_REQUEST_RECIPIENT_DEVICE), @@ -363,10 +361,10 @@ tusb_error_t enumeration_body_subtask(void) 8, enum_data_buffer ), error ); - - SUBTASK_ASSERT_STATUS(error); // TODO some slow device is observed to fail the very fist controler xfer, can try more times + SUBTASK_ASSERT_STATUS(error); // TODO some slow device is observed to fail the very fist controller xfer, can try more times hcd_port_reset( usbh_devices[0].core_id ); // reset port after 8 byte descriptor + osal_task_delay(50); // reset is recommended to last 50 ms //------------- Set new address -------------// new_addr = get_new_address();