diff options
| author | hathach <[email protected]> | 2013-09-22 18:44:55 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2013-09-22 18:44:55 +0700 |
| commit | cc91a73cdc8c6f46adfcae38e4c36d819a49ab01 (patch) | |
| tree | 829f83c189fd25b2eb28374ec4392a1860f2d8ca /tinyusb/class | |
| parent | 57088638598ccd0ea185debb8ca0fc7cbb404587 (diff) | |
fix pingstate for highspeed bulk out transfer
temp implementation of msc host --> can issue inquiry command
Diffstat (limited to 'tinyusb/class')
| -rw-r--r-- | tinyusb/class/msc.h | 30 | ||||
| -rw-r--r-- | tinyusb/class/msc_host.c | 66 | ||||
| -rw-r--r-- | tinyusb/class/msc_host.h | 8 |
3 files changed, 98 insertions, 6 deletions
diff --git a/tinyusb/class/msc.h b/tinyusb/class/msc.h index c8662089e..f52cdc343 100644 --- a/tinyusb/class/msc.h +++ b/tinyusb/class/msc.h @@ -76,6 +76,20 @@ enum { MSC_REQUEST_RESET = 255 }; +typedef enum { + SCSI_CMD_TEST_UNIT_READY = 0x00, + SCSI_CMD_INQUIRY = 0x12, + SCSI_CMD_READ_CAPACITY_10 = 0x25, + SCSI_CMD_READ_10 = 0x28, + SCSI_CMD_WRITE_10 = 0x2A, +}scsi_cmd_type_t; + +typedef enum { + MSC_CSW_STATUS_PASSED = 0, + MSC_CSW_STATUS_FAILED, + MSC_CSW_STATUS_PHASE_ERROR +}msc_csw_status_t; + typedef ATTR_PACKED_STRUCT(struct) { uint32_t signature; // const 0x43425355 uint32_t tag; @@ -100,6 +114,16 @@ STATIC_ASSERT(sizeof(msc_cmd_status_wrapper_t) == 13, "size is not correct"); //--------------------------------------------------------------------+ // SCSI Primary Command (SPC-4) //--------------------------------------------------------------------+ +typedef ATTR_PACKED_STRUCT(struct) { + uint8_t operation_code; + uint8_t reserve; + uint8_t page_code; + uint16_t alloc_length; + uint8_t control; +} scsi_inquiry_t; + +STATIC_ASSERT(sizeof(scsi_inquiry_t) == 6, "size is not correct"); + typedef ATTR_PACKED_STRUCT(struct) { uint8_t peripheral_device_type : 5; @@ -141,9 +165,9 @@ typedef ATTR_PACKED_STRUCT(struct) uint8_t vendor_id[8]; uint8_t product_id[16]; uint8_t product_revision[4]; -} msc_scsi_inquiry_t; +} scsi_inquiry_data_t; -STATIC_ASSERT(sizeof(msc_scsi_inquiry_t) == 36, "size is not correct"); +STATIC_ASSERT(sizeof(scsi_inquiry_data_t) == 36, "size is not correct"); //--------------------------------------------------------------------+ // SCSI Block Command (SBC-3) @@ -153,6 +177,8 @@ typedef struct { uint8_t block_length[4]; } msc_scsi_read_capacity10_t; + + #ifdef __cplusplus } #endif diff --git a/tinyusb/class/msc_host.c b/tinyusb/class/msc_host.c index f5c4dbd25..f4d72cf9c 100644 --- a/tinyusb/class/msc_host.c +++ b/tinyusb/class/msc_host.c @@ -56,8 +56,12 @@ typedef struct { uint8_t interface_number; uint8_t max_lun; + uint8_t vendor_id[8]; + uint8_t product_id[16]; + msc_cmd_block_wrapper_t cbw; msc_cmd_status_wrapper_t csw; + 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 @@ -70,8 +74,24 @@ STATIC_VAR uint8_t msch_buffer[10] TUSB_CFG_ATTR_USBRAM; //--------------------------------------------------------------------+ //--------------------------------------------------------------------+ -// IMPLEMENTATION +// PUBLIC API //--------------------------------------------------------------------+ +bool tusbh_msc_is_mounted(uint8_t dev_addr) +{ + return tusbh_device_is_configured(dev_addr) && + pipehandle_is_valid(msch_data[dev_addr-1].bulk_in) && + pipehandle_is_valid(msch_data[dev_addr-1].bulk_out); +} + +uint8_t const * tusbh_msc_get_vendor_name(uint8_t dev_addr) +{ + return tusbh_msc_is_mounted(dev_addr) ? msch_data[dev_addr-1].vendor_id : NULL; +} + +uint8_t const * tusbh_msc_get_product_name(uint8_t dev_addr) +{ + return tusbh_msc_is_mounted(dev_addr) ? msch_data[dev_addr-1].product_id : NULL; +} //--------------------------------------------------------------------+ // CLASS-USBH API (don't require to verify parameters) @@ -123,7 +143,37 @@ tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con msch_data[dev_addr-1].max_lun = msch_buffer[0]; //------------- SCSI Inquiry -------------// + msch_data[dev_addr-1].cbw = (msc_cmd_block_wrapper_t) { + .signature = 0x43425355, + .tag = 0xCAFECAFE, + .xfer_bytes = sizeof(scsi_inquiry_data_t), + .flags = TUSB_DIR_DEV_TO_HOST_MASK, + .lun = 0, + .cmd_len = sizeof(scsi_inquiry_t), + }; + scsi_inquiry_t cmd_inquiry = + { + .operation_code = SCSI_CMD_INQUIRY, + .alloc_length = sizeof(scsi_inquiry_data_t) + }; + memcpy(msch_data[dev_addr-1].cbw.command, &cmd_inquiry, sizeof(scsi_inquiry_t)); + + hcd_pipe_xfer(msch_data[dev_addr-1].bulk_out, &msch_data[dev_addr-1].cbw, sizeof(msc_cmd_block_wrapper_t), false); + hcd_pipe_xfer(msch_data[dev_addr-1].bulk_in , msch_data[dev_addr-1].buffer, sizeof(scsi_inquiry_data_t), false); + hcd_pipe_xfer(msch_data[dev_addr-1].bulk_in , &msch_data[dev_addr-1].csw, sizeof(msc_cmd_status_wrapper_t), true); + + // TODO timeout required, a proper synchronization +// while( !hcd_pipe_is_idle(msch_data[dev_addr-1].bulk_in) ) + { + 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); tusbh_msc_mounted_cb(dev_addr); @@ -145,5 +195,19 @@ void msch_close(uint8_t dev_addr) memclr_(&msch_data[dev_addr-1], sizeof(msch_interface_t)); } +//--------------------------------------------------------------------+ +// INTERNAL & HELPER +//--------------------------------------------------------------------+ +//static tusb_error_t scsi_command_send(msc_cmd_block_wrapper_t const * cbw, uint8_t * buffer, msc_cmd_status_wrapper_t const * csw) +//{ +// tusb_error_t error; +// +// OSAL_SUBTASK_BEGIN +// +// hcd_pipe_xfer() +// +// OSAL_SUBTASK_END +//} + #endif diff --git a/tinyusb/class/msc_host.h b/tinyusb/class/msc_host.h index d6a976397..1fd99788d 100644 --- a/tinyusb/class/msc_host.h +++ b/tinyusb/class/msc_host.h @@ -58,10 +58,12 @@ //--------------------------------------------------------------------+ // MASS STORAGE Application API //--------------------------------------------------------------------+ -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; +bool tusbh_msc_is_mounted(uint8_t dev_addr) ATTR_PURE ATTR_WARN_UNUSED_RESULT; +tusb_interface_status_t tusbh_msc_status(uint8_t dev_addr) ATTR_WARN_UNUSED_RESULT; +uint8_t const * tusbh_msc_get_vendor_name(uint8_t dev_addr); +uint8_t const * tusbh_msc_get_product_name(uint8_t dev_addr); -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_inquiry(uint8_t dev_addr, uint8_t instance_num, scsi_inquiry_data_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; |
