* to a FAT library to give file-level access to an attached device's contents.\r
*\r
* \note Many Mass Storage devices on the market are non-compliant to the\r
- * specifications and thus can proove difficult to interface with. It\r
- * may be neccesary to retry the functions in the module several times\r
+ * specifications and thus can prove difficult to interface with. It\r
+ * may be necessary to retry the functions in the module several times\r
* after they have returned and error to successfully send the command\r
* to the device. Some devices may also need to have the stream function\r
* timeout period extended beyond 100ms (some badly designed devices exceeding\r
\r
/* Globals: */\r
/** Current CBW to send to the device. This is automatically filled by the routines\r
- * in this file and is not externally accessable.\r
+ * in this file and is not externally accessible.\r
*/\r
static CommandBlockWrapper_t SCSICommandBlock;\r
\r
/** Current CSW received from the device. This is automatically filled by the routines\r
- * in this file and is externally accessable so that the return codes may be checked.\r
+ * in this file and is externally accessible so that the return codes may be checked.\r
*/\r
CommandStatusWrapper_t SCSICommandStatus;\r
\r
/** Current Tag value used in issued CBWs to the device. This is automatically incremented\r
- * by the routines in this file, and is not externally accessable.\r
+ * by the routines in this file, and is not externally accessible.\r
*/\r
static uint32_t MassStore_Tag = 1;\r
\r
{\r
uint8_t ErrorCode = PIPE_RWSTREAM_ERROR_NoError;\r
\r
- /* Each transmission should have a unique tag value, excluding valued 0 and 0xFFFFFFFF */\r
+ /* Each transmission should have a unique tag value, excluding values 0 and 0xFFFFFFFF */\r
if (++MassStore_Tag == 0xFFFFFFFF)\r
MassStore_Tag = 1;\r
\r
return ErrorCode;\r
\r
/* Send the data in the OUT pipe to the attached device */\r
- Pipe_ClearCurrentBank();\r
+ Pipe_ClearOUT();\r
\r
/* Some buggy devices require a delay here before the pipe freezing or they will lock up */\r
USB_Host_WaitMS(1);\r
Pipe_Unfreeze();\r
\r
/* Wait until data received in the IN pipe */\r
- while (!(Pipe_ReadWriteAllowed()))\r
+ while (!(Pipe_IsINReceived()))\r
{\r
/* Check to see if a new frame has been issued (1ms elapsed) */\r
if (USB_INT_HasOccurred(USB_INT_HSOFI))\r
{\r
- /* Clear the flag and decrement the timout period counter */\r
+ /* Clear the flag and decrement the timeout period counter */\r
USB_INT_Clear(USB_INT_HSOFI);\r
TimeoutMSRem--;\r
\r
/* Read in the block data from the pipe */\r
if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_ERROR_NoError)\r
return ErrorCode;\r
+\r
+ /* Acknowledge the packet */\r
+ Pipe_ClearIN();\r
}\r
else\r
{\r
/* Write the block data to the pipe */\r
if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_ERROR_NoError)\r
return ErrorCode;\r
+\r
+ /* Acknowledge the packet */\r
+ Pipe_ClearOUT();\r
}\r
- \r
- /* Acknowledge the packet */\r
- Pipe_ClearCurrentBank();\r
\r
/* Some buggy devices require a delay here before the pipe freezing or they will lock up */\r
USB_Host_WaitMS(1);\r
{\r
uint8_t ErrorCode = PIPE_RWSTREAM_ERROR_NoError;\r
\r
+ /* If an error in the command ocurred, abort */\r
+ if ((ErrorCode == MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_ERROR_NoError)\r
+ return ErrorCode;\r
+\r
/* Select the IN data pipe for data reception */\r
Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);\r
Pipe_Unfreeze();\r
return ErrorCode;\r
\r
/* Clear the data ready for next reception */\r
- Pipe_ClearCurrentBank();\r
+ Pipe_ClearIN();\r
\r
/* Some buggy devices require a delay here before the pipe freezing or they will lock up */\r
USB_Host_WaitMS(1);\r
*/\r
uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum)\r
{\r
- USB_HostRequest = (USB_Host_Request_Header_t)\r
+ USB_ControlRequest = (USB_Request_Header_t)\r
{\r
- bmRequestType: (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),\r
- bRequest: REQ_ClearFeature,\r
- wValue: FEATURE_ENDPOINT_HALT,\r
- wIndex: EndpointNum,\r
- wLength: 0,\r
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),\r
+ .bRequest = REQ_ClearFeature,\r
+ .wValue = FEATURE_ENDPOINT_HALT,\r
+ .wIndex = EndpointNum,\r
+ .wLength = 0,\r
};\r
\r
+ /* Select the control pipe for the request transfer */\r
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
+\r
return USB_Host_SendControlRequest(NULL);\r
}\r
\r
*/\r
uint8_t MassStore_MassStorageReset(void)\r
{\r
- USB_HostRequest = (USB_Host_Request_Header_t)\r
+ USB_ControlRequest = (USB_Request_Header_t)\r
{\r
- bmRequestType: (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),\r
- bRequest: REQ_MassStorageReset,\r
- wValue: 0,\r
- wIndex: 0,\r
- wLength: 0,\r
+ .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),\r
+ .bRequest = REQ_MassStorageReset,\r
+ .wValue = 0,\r
+ .wIndex = 0,\r
+ .wLength = 0,\r
};\r
\r
+ /* Select the control pipe for the request transfer */\r
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
+\r
return USB_Host_SendControlRequest(NULL);\r
}\r
\r
{\r
uint8_t ErrorCode;\r
\r
- USB_HostRequest = (USB_Host_Request_Header_t)\r
+ USB_ControlRequest = (USB_Request_Header_t)\r
{\r
- bmRequestType: (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),\r
- bRequest: REQ_GetMaxLUN,\r
- wValue: 0,\r
- wIndex: 0,\r
- wLength: 1,\r
+ .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),\r
+ .bRequest = REQ_GetMaxLUN,\r
+ .wValue = 0,\r
+ .wIndex = 0,\r
+ .wLength = 1,\r
};\r
\r
+ /* Select the control pipe for the request transfer */\r
+ Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
+\r
if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) == HOST_SENDCONTROL_SetupStalled)\r
{\r
/* Clear the pipe stall */\r
/* Create a CBW with a SCSI command to issue REQUEST SENSE command */\r
SCSICommandBlock = (CommandBlockWrapper_t)\r
{\r
- Header:\r
+ .Header =\r
{\r
- Signature: CBW_SIGNATURE,\r
- Tag: MassStore_Tag,\r
- DataTransferLength: sizeof(SCSI_Request_Sense_Response_t),\r
- Flags: COMMAND_DIRECTION_DATA_IN,\r
- LUN: LUNIndex,\r
- SCSICommandLength: 6\r
+ .Signature = CBW_SIGNATURE,\r
+ .Tag = MassStore_Tag,\r
+ .DataTransferLength = sizeof(SCSI_Request_Sense_Response_t),\r
+ .Flags = COMMAND_DIRECTION_DATA_IN,\r
+ .LUN = LUNIndex,\r
+ .SCSICommandLength = 6\r
},\r
\r
- SCSICommandData:\r
+ .SCSICommandData =\r
{\r
SCSI_CMD_REQUEST_SENSE,\r
0x00, // Reserved\r
/* Create a CBW with a SCSI command to read in the given blocks from the device */\r
SCSICommandBlock = (CommandBlockWrapper_t)\r
{\r
- Header:\r
+ .Header =\r
{\r
- Signature: CBW_SIGNATURE,\r
- Tag: MassStore_Tag,\r
- DataTransferLength: ((uint32_t)Blocks * BlockSize),\r
- Flags: COMMAND_DIRECTION_DATA_IN,\r
- LUN: LUNIndex,\r
- SCSICommandLength: 10\r
+ .Signature = CBW_SIGNATURE,\r
+ .Tag = MassStore_Tag,\r
+ .DataTransferLength = ((uint32_t)Blocks * BlockSize),\r
+ .Flags = COMMAND_DIRECTION_DATA_IN,\r
+ .LUN = LUNIndex,\r
+ .SCSICommandLength = 10\r
},\r
\r
- SCSICommandData:\r
+ .SCSICommandData =\r
{\r
SCSI_CMD_READ_10,\r
0x00, // Unused (control bits, all off)\r
/* Create a CBW with a SCSI command to write the given blocks to the device */\r
SCSICommandBlock = (CommandBlockWrapper_t)\r
{\r
- Header:\r
+ .Header =\r
{\r
- Signature: CBW_SIGNATURE,\r
- Tag: MassStore_Tag,\r
- DataTransferLength: ((uint32_t)Blocks * BlockSize),\r
- Flags: COMMAND_DIRECTION_DATA_OUT,\r
- LUN: LUNIndex,\r
- SCSICommandLength: 10\r
+ .Signature = CBW_SIGNATURE,\r
+ .Tag = MassStore_Tag,\r
+ .DataTransferLength = ((uint32_t)Blocks * BlockSize),\r
+ .Flags = COMMAND_DIRECTION_DATA_OUT,\r
+ .LUN = LUNIndex,\r
+ .SCSICommandLength = 10\r
},\r
\r
- SCSICommandData:\r
+ .SCSICommandData =\r
{\r
SCSI_CMD_WRITE_10,\r
0x00, // Unused (control bits, all off)\r
/* Create a CBW with a SCSI command to issue TEST UNIT READY command */\r
SCSICommandBlock = (CommandBlockWrapper_t)\r
{\r
- Header:\r
+ .Header =\r
{\r
- Signature: CBW_SIGNATURE,\r
- Tag: MassStore_Tag,\r
- DataTransferLength: 0,\r
- Flags: COMMAND_DIRECTION_DATA_IN,\r
- LUN: LUNIndex,\r
- SCSICommandLength: 6\r
+ .Signature = CBW_SIGNATURE,\r
+ .Tag = MassStore_Tag,\r
+ .DataTransferLength = 0,\r
+ .Flags = COMMAND_DIRECTION_DATA_IN,\r
+ .LUN = LUNIndex,\r
+ .SCSICommandLength = 6\r
},\r
\r
- SCSICommandData:\r
+ .SCSICommandData =\r
{\r
SCSI_CMD_TEST_UNIT_READY,\r
0x00, // Reserved\r
/* Create a CBW with a SCSI command to issue READ CAPACITY command */\r
SCSICommandBlock = (CommandBlockWrapper_t)\r
{\r
- Header:\r
+ .Header =\r
{\r
- Signature: CBW_SIGNATURE,\r
- Tag: MassStore_Tag,\r
- DataTransferLength: 8,\r
- Flags: COMMAND_DIRECTION_DATA_IN,\r
- LUN: LUNIndex,\r
- SCSICommandLength: 10\r
+ .Signature = CBW_SIGNATURE,\r
+ .Tag = MassStore_Tag,\r
+ .DataTransferLength = 8,\r
+ .Flags = COMMAND_DIRECTION_DATA_IN,\r
+ .LUN = LUNIndex,\r
+ .SCSICommandLength = 10\r
},\r
\r
- SCSICommandData:\r
+ .SCSICommandData =\r
{\r
SCSI_CMD_READ_CAPACITY_10,\r
0x00, // Reserved\r
/* Create a CBW with a SCSI command to issue PREVENT ALLOW MEDIUM REMOVAL command */\r
SCSICommandBlock = (CommandBlockWrapper_t)\r
{\r
- Header:\r
+ .Header =\r
{\r
- Signature: CBW_SIGNATURE,\r
- Tag: MassStore_Tag,\r
- DataTransferLength: 0,\r
- Flags: COMMAND_DIRECTION_DATA_OUT,\r
- LUN: LUNIndex,\r
- SCSICommandLength: 6\r
+ .Signature = CBW_SIGNATURE,\r
+ .Tag = MassStore_Tag,\r
+ .DataTransferLength = 0,\r
+ .Flags = COMMAND_DIRECTION_DATA_OUT,\r
+ .LUN = LUNIndex,\r
+ .SCSICommandLength = 6\r
},\r
\r
- SCSICommandData:\r
+ .SCSICommandData =\r
{\r
SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL,\r
0x00, // Reserved\r