41 #if (MODE_DEVICE_SUPPORTED && TUSB_CFG_DEVICE_MSC)
43 #define _TINY_USB_SOURCE_FILE_
54 uint8_t scsi_data[64];
57 #if defined (__ICCARM__) && (TUSB_CFG_MCU == MCU_LPC11UXX || TUSB_CFG_MCU == MCU_LPC13UXX)
64 uint8_t interface_number;
72 static bool read10_write10_data_xfer(mscd_interface_t* p_msc);
79 memclr_(&mscd_data,
sizeof(mscd_interface_t));
82 void mscd_close(uint8_t coreid)
84 memclr_(&mscd_data,
sizeof(mscd_interface_t));
93 mscd_interface_t * p_msc = &mscd_data;
97 for(uint32_t i=0; i<2; i++)
100 TUSB_XFER_BULK == p_endpoint->
bmAttributes.xfer, TUSB_ERROR_DESCRIPTOR_CORRUPTED);
103 &p_msc->edpt_in : &p_msc->edpt_out;
105 (*p_edpt_hdl) = dcd_pipe_open(coreid, p_endpoint, p_interface_desc->
bInterfaceClass);
106 ASSERT( endpointhandle_is_valid(*p_edpt_hdl), TUSB_ERROR_DCD_FAILED);
118 ASSERT_STATUS( dcd_pipe_xfer(p_msc->edpt_out, (uint8_t*) &p_msc->cbw,
sizeof(
msc_cmd_block_wrapper_t),
true) );
120 return TUSB_ERROR_NONE;
125 ASSERT(p_request->bmRequestType_bit.type == TUSB_REQUEST_TYPE_CLASS, TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT);
127 mscd_interface_t * p_msc = &mscd_data;
129 switch(p_request->bRequest)
132 dcd_pipe_control_xfer(coreid, TUSB_DIR_HOST_TO_DEV, NULL, 0,
false);
136 p_msc->scsi_data[0] = p_msc->max_lun;
137 dcd_pipe_control_xfer(coreid, TUSB_DIR_DEV_TO_HOST, p_msc->scsi_data, 1,
false);
141 return TUSB_ERROR_DCD_CONTROL_REQUEST_NOT_SUPPORT;
144 return TUSB_ERROR_NONE;
152 static bool is_waiting_read10_write10 =
false;
154 mscd_interface_t *
const p_msc = &mscd_data;
159 if ( !is_waiting_read10_write10 )
161 if ( endpointhandle_is_equal(p_msc->edpt_in, edpt_hdl) )
return TUSB_ERROR_NONE;
163 ASSERT( endpointhandle_is_equal(p_msc->edpt_out, edpt_hdl) &&
165 event == TUSB_EVENT_XFER_COMPLETE &&
174 void const *p_buffer = NULL;
175 uint16_t actual_length = (uint16_t) p_cbw->
xfer_bytes;
185 ASSERT( p_cbw->
xfer_bytes >= actual_length, TUSB_ERROR_INVALID_PARA );
186 ASSERT(
sizeof(p_msc->scsi_data) >= actual_length, TUSB_ERROR_NOT_ENOUGH_MEMORY);
190 if ( p_buffer == NULL || actual_length == 0 )
192 ASSERT_STATUS( dcd_pipe_stall(edpt_data) );
196 memcpy(p_msc->scsi_data, p_buffer, actual_length);
197 ASSERT_STATUS( dcd_pipe_queue_xfer( edpt_data, p_msc->scsi_data, actual_length ) );
206 is_waiting_read10_write10 = !read10_write10_data_xfer(p_msc);
211 if (!is_waiting_read10_write10)
219 return TUSB_ERROR_NONE;
223 static bool read10_write10_data_xfer(mscd_interface_t* p_msc)
232 uint32_t
const lba =
__be2n(p_readwrite->
lba);
233 uint16_t
const block_count = __be2n_16(p_readwrite->
block_count);
234 void *p_buffer = NULL;
238 xferred_block = min16_of(xferred_block, block_count);
240 uint16_t
const xferred_byte = xferred_block * (p_cbw->
xfer_bytes / block_count);
242 if ( 0 == xferred_block )
247 (void) dcd_pipe_stall(edpt_hdl);
250 }
else if (xferred_block < block_count)
252 ASSERT_STATUS( dcd_pipe_xfer( edpt_hdl, p_buffer, xferred_byte,
true) );
255 p_readwrite->
lba =
__n2be(lba+xferred_block);
256 p_readwrite->
block_count = __n2be_16(block_count - xferred_block);
263 ASSERT_STATUS( dcd_pipe_queue_xfer( edpt_hdl, p_buffer, xferred_byte) );
uint32_t xfer_bytes
The number of bytes of data that the host expects to transfer on the Bulk-In or Bulk-Out endpoint (as...
USB Standard Interface Descriptor (section 9.6.1 table 9-12)
uint32_t tag
The device shall set this field to the value received in the dCBWTag of the associated CBW...
#define __n2be(x)
built-in function to convert 32-bit from native to Big Endian
uint32_t data_residue
For Data-Out the device shall report in the dCSWDataResiduethe difference between the amount of data ...
uint16_t tusbd_msc_read10_cb(uint8_t coreid, uint8_t lun, void **pp_buffer, uint32_t lba, uint16_t block_count)
Callback that is invoked when tinyusb stack received SCSI_CMD_READ_10 command from host...
uint8_t bInterfaceProtocol
Protocol code (assigned by the USB). These codes are qualified by the value of the bInterfaceClass ...
Constant value of 43425355h (little endian)
Constant value of 53425355h (little endian)
uint8_t lun
The device Logical Unit Number (LUN) to which the command block is being sent. For devices that suppo...
uint32_t signature
Signature that helps identify this data packet as a CBW. The signature field shall contain the value ...
The WRITE (10) command requests thatthe device server transfer the specified logical block(s) from th...
#define BIT_TEST_(x, n)
check if n-th bit of x is 1
#define __be2n(x)
built-in function to convert 32-bit from Big Endian to native
The READ (10) command requests that the device server read the specified logical block(s) and transfe...
struct tusb_descriptor_endpoint_t::@8 bmAttributes
This field describes the endpoint's attributes when it is configured using the bConfigurationValue. Bits 1..0: Transfer Type - 00 = Control - 01 = Isochronous - 10 = Bulk - 11 = Interrupt If not an isochronous endpoint, bits 5..2 are reserved and must be set to zero. If isochronous, they are defined as follows: Bits 3..2: Synchronization Type - 00 = No Synchronization - 01 = Asynchronous - 10 = Adaptive - 11 = Synchronous Bits 5..4: Usage Type - 00 = Data endpoint - 01 = Feedback endpoint - 10 = Implicit feedback Data endpoint - 11 = Reserved Refer to Chapter 5 of USB 2.0 specification for more information. All other bits are reserved and must be reset to zero. Reserved bits must be ignored by the host.
uint16_t block_count
Number of Blocks used by this command.
#define TUSB_CFG_ATTR_USBRAM
uint32_t lba
The first Logical Block Address (LBA) accessed by this command.
void tusbd_msc_mounted_cb(uint8_t coreid)
Callback function that will be invoked when this interface is mounted (configured) by USB host...
uint8_t bDescriptorType
ENDPOINT Descriptor Type.
uint8_t bInterfaceSubClass
Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bInterfaceCla...
USB Standard Endpoint Descriptor (section 9.6.1 table 9-13)
This request is used to reset the mass storage device and its associated interface. This class-specific request shall ready the device for the next CBW from the host.
uint8_t bInterfaceNumber
Number of this interface. Zero-based value identifying the index in the array of concurrent interface...
uint32_t tag
Tag sent by the host. The device shall echo the contents of this field back to the host in the dCSWTa...
The Get Max LUN device request is used to determine the number of logical units supported by the devi...
uint8_t dir
Bit 7 of this field define transfer direction - 0 : Data-Out from host to the device. - 1 : Data-In from the device to the host.
tusb_error_t
Error Code returned.
uint16_t tusbd_msc_write10_cb(uint8_t coreid, uint8_t lun, void **pp_buffer, uint32_t lba, uint16_t block_count)
Callback that is invoked when tinyusb stack received SCSI_CMD_WRITE_10 command from host...
SCSI transparent command set.
uint8_t command[16]
The command block to be executed by the device. The device shall interpret the first cmd_len bytes in...
uint8_t bInterfaceClass
Class code (assigned by the USB-IF).
uint32_t signature
Signature that helps identify this data packet as a CSW. The signature field shall contain the value ...
uint8_t status
indicates the success or failure of the command. Values from msc_csw_status_t
uint8_t bEndpointAddress
The address of the endpoint on the USB device described by this descriptor. The address is encoded as...
void tusbd_msc_unmounted_cb(uint8_t coreid)
Callback function that will be invoked when this interface is unmounted (bus reset/unplugged) ...
msc_csw_status_t tusbd_msc_scsi_cb(uint8_t coreid, uint8_t lun, uint8_t scsi_cmd[16], void const **pp_buffer, uint16_t *p_length)
Callback that is invoked when tinyusb stack received an SCSI command other than SCSI_CMD_WRITE_10 and...