Commit 58e42c6c authored by Dean Camera's avatar Dean Camera
Browse files

Fixed SPI driver init function not clearing SPI2X bit when not needed.

Fixed PREVENT ALLOW MEDIUM REMOVAL command issuing in the MassStorageHost demo using incorrect parameters (thanks to Mike Alex).

Fixed MassStorageHost demo broken due to an incorrect if statement test in MassStore_GetReturnedStatus().
parent e21b620b
......@@ -116,9 +116,9 @@
*/
typedef struct
{
uint8_t ResponseCode;
uint8_t ResponseCode;
uint8_t SegmentNumber;
uint8_t SegmentNumber;
unsigned char SenseKey : 4;
unsigned char _RESERVED1 : 1;
......
......@@ -212,46 +212,51 @@ TASK(USB_MassStore_Host)
/* Indicate device busy via the status LEDs */
UpdateStatus(Status_Busy);
/* Reset the Mass Storage device interface, ready for use */
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
{
ShowDiskReadError(PSTR("Mass Storage Reset"), ErrorCode);
break;
}
/* Send the request, display error and wait for device detach if request fails */
if ((ErrorCode = MassStore_GetMaxLUN(&MassStore_MaxLUNIndex)) != HOST_SENDCONTROL_Successful)
{
ShowDiskReadError(PSTR("Get Max LUN"), ErrorCode);
ShowDiskReadError(PSTR("Get Max LUN"), false, ErrorCode);
break;
}
/* Print number of LUNs detected in the attached device */
printf_P(PSTR("Total LUNs: %d.\r\n"), (MassStore_MaxLUNIndex + 1));
/* Set the prevent removal flag for the device, allowing it to be accessed */
if ((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0)
/* Reset the Mass Storage device interface, ready for use */
if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
{
ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), ErrorCode);
ShowDiskReadError(PSTR("Mass Storage Reset"), false, ErrorCode);
break;
}
/* Get sense data from the device - many devices will not accept any other commands until the sense data
* is read - both on start-up and after a failed command */
SCSI_Request_Sense_Response_t SenseData;
if ((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0)
if (((ErrorCode = MassStore_RequestSense(0, &SenseData)) != 0) || (SCSICommandStatus.Status != Command_Pass))
{
ShowDiskReadError(PSTR("Request Sense"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);
break;
}
/* Set the prevent removal flag for the device, allowing it to be accessed */
if (((ErrorCode = MassStore_PreventAllowMediumRemoval(0, true)) != 0) || (SCSICommandStatus.Status != Command_Pass))
{
ShowDiskReadError(PSTR("Request Sense"), ErrorCode);
ShowDiskReadError(PSTR("Prevent/Allow Medium Removal"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);
break;
}
puts_P(PSTR("Waiting until ready"));
puts_P(PSTR("Waiting until ready.."));
/* Wait until disk ready */
do
{
Serial_TxByte('.');
MassStore_TestUnitReady(0);
if ((ErrorCode = MassStore_TestUnitReady(0)) != 0)
{
ShowDiskReadError(PSTR("Test Unit Ready"), false, ErrorCode);
break;
}
}
while ((SCSICommandStatus.Status != Command_Pass) && USB_IsConnected);
......@@ -265,28 +270,26 @@ TASK(USB_MassStore_Host)
SCSI_Capacity_t DiskCapacity;
/* Retrieve disk capacity */
if ((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0)
if (((ErrorCode = MassStore_ReadCapacity(0, &DiskCapacity)) != 0) || (SCSICommandStatus.Status != Command_Pass))
{
ShowDiskReadError(PSTR("Read Capacity"), ErrorCode);
ShowDiskReadError(PSTR("Read Capacity"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);
break;
}
/* Display the disk capacity in blocks * block size bytes */
printf_P(PSTR("%lu blocks of %lu bytes.\r\n"), DiskCapacity.Blocks, DiskCapacity.BlockSize);
/* Create a new buffer capabable of holding a single block from the device */
uint8_t BlockBuffer[DiskCapacity.BlockSize];
/* Read in the first 512 byte block from the device */
if ((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
if (((ErrorCode = MassStore_ReadDeviceBlock(0, 0x00000000, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0) ||
(SCSICommandStatus.Status != Command_Pass))
{
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
ShowDiskReadError(PSTR("Read Device Block"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);
break;
}
/* Show the number of bytes not transferred in the previous command */
printf_P(PSTR("Transfer Residue: %lu\r\n"), SCSICommandStatus.DataTransferResidue);
puts_P(PSTR("\r\nContents of first block:\r\n"));
/* Print out the first block in both HEX and ASCII, 16 bytes per line */
......@@ -330,9 +333,10 @@ TASK(USB_MassStore_Host)
for (uint32_t CurrBlock = 0; CurrBlock < DiskCapacity.Blocks; CurrBlock++)
{
/* Read in the next block of data from the device */
if ((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlock, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0)
if (((ErrorCode = MassStore_ReadDeviceBlock(0, CurrBlock, 1, DiskCapacity.BlockSize, BlockBuffer)) != 0) ||
(SCSICommandStatus.Status != Command_Pass))
{
ShowDiskReadError(PSTR("Read Device Block"), ErrorCode);
ShowDiskReadError(PSTR("Read Device Block"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);
break;
}
......@@ -399,14 +403,24 @@ void UpdateStatus(uint8_t CurrentStatus)
* continuing.
*
* \param CommandString ASCII string located in PROGMEM space indicating what operation failed
* \param FailedAtSCSILayer Indicates if the command failed at the (logical) SCSI layer or at the physical USB layer
* \param ErrorCode Error code of the function which failed to complete successfully
*/
void ShowDiskReadError(char* CommandString, uint8_t ErrorCode)
void ShowDiskReadError(char* CommandString, bool FailedAtSCSILayer, uint8_t ErrorCode)
{
/* Display the error code */
printf_P(PSTR(ESC_BG_RED "Command error (%S).\r\n"), CommandString);
printf_P(PSTR(" -- Error Code: %d"), ErrorCode);
if (CommandFailed)
{
/* Display the error code */
printf_P(PSTR(ESC_BG_RED "SCSI command error (%S).\r\n"), CommandString);
printf_P(PSTR(" -- Status Code: %d"), ErrorCode);
}
else
{
/* Display the error code */
printf_P(PSTR(ESC_BG_RED "Command error (%S).\r\n"), CommandString);
printf_P(PSTR(" -- Error Code: %d"), ErrorCode);
}
Pipe_Freeze();
/* Indicate device error via the status LEDs */
......
......@@ -79,7 +79,7 @@
HANDLES_EVENT(USB_DeviceEnumerationFailed);
/* Function Prototypes: */
void ShowDiskReadError(char* CommandString, uint8_t ErrorCode);
void ShowDiskReadError(char* CommandString, bool FailedAtSCSILayer, uint8_t ErrorCode);
void UpdateStatus(uint8_t CurrentStatus);
#endif
......@@ -89,10 +89,9 @@ static uint8_t MassStore_SendCommand(void)
/* Send the data in the OUT pipe to the attached device */
Pipe_ClearOUT();
/* Some buggy devices require a delay here before the pipe freezing or they will lock up */
USB_Host_WaitMS(1);
while(!(Pipe_IsOUTReady()));
/* Freeze pipe after use */
Pipe_Freeze();
......@@ -199,10 +198,9 @@ static uint8_t MassStore_SendReceiveData(void* BufferPtr)
/* Acknowledge the packet */
Pipe_ClearOUT();
while (!(Pipe_IsOUTReady()));
}
/* Some buggy devices require a delay here before the pipe freezing or they will lock up */
USB_Host_WaitMS(1);
/* Freeze used pipe after use */
Pipe_Freeze();
......@@ -219,7 +217,7 @@ static uint8_t MassStore_GetReturnedStatus(void)
uint8_t ErrorCode = PIPE_RWSTREAM_ERROR_NoError;
/* If an error in the command ocurred, abort */
if ((ErrorCode == MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_ERROR_NoError)
if ((ErrorCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_ERROR_NoError)
return ErrorCode;
/* Select the IN data pipe for data reception */
......@@ -232,9 +230,6 @@ static uint8_t MassStore_GetReturnedStatus(void)
/* Clear the data ready for next reception */
Pipe_ClearIN();
/* Some buggy devices require a delay here before the pipe freezing or they will lock up */
USB_Host_WaitMS(1);
/* Freeze the IN pipe after use */
Pipe_Freeze();
......@@ -587,7 +582,7 @@ uint8_t MassStore_ReadCapacity(const uint8_t LUNIndex, SCSI_Capacity_t* const Ca
{
.Signature = CBW_SIGNATURE,
.Tag = MassStore_Tag,
.DataTransferLength = 8,
.DataTransferLength = sizeof(SCSI_Capacity_t),
.Flags = COMMAND_DIRECTION_DATA_IN,
.LUN = LUNIndex,
.SCSICommandLength = 10
......@@ -680,7 +675,7 @@ uint8_t MassStore_PreventAllowMediumRemoval(const uint8_t LUNIndex, const bool P
MassStore_SendCommand();
/* Read in the returned CSW from the device */
if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_ERROR_NoError)
if ((ReturnCode = MassStore_GetReturnedStatus()))
{
Pipe_Freeze();
return ReturnCode;
......
......@@ -109,10 +109,9 @@
*/
typedef struct
{
unsigned char ReponseCode : 7;
unsigned char Valid : 1;
uint8_t SegmentNumber;
uint8_t ReponseCode;
uint8_t SegmentNumber;
unsigned char SenseKey : 4;
unsigned char _RESERVED1 : 1;
......
......@@ -63,6 +63,9 @@
* - Renamed the FEATURELESS_CONTROL_ONLY_DEVICE compile-time token to CONTROL_ONLY_DEVICE
* - Endpoint configuration is now refined to give better output when all configurations have static inputs - removed the now useless
* STATIC_ENDPOINT_CONFIGURATION compile time token
* - Fixed SPI driver init function not clearing SPI2X bit when not needed
* - Fixed PREVENT ALLOW MEDIUM REMOVAL command issuing in the MassStorageHost demo using incorrect parameters (thanks to Mike Alex)
* - Fixed MassStorageHost demo broken due to an incorrect if statement test in MassStore_GetReturnedStatus()
*
*
* \section Sec_ChangeLog090401 Version 090401
......
......@@ -102,7 +102,9 @@
(PrescalerMask & ~SPI_USE_DOUBLESPEED));
if (PrescalerMask & SPI_USE_DOUBLESPEED)
SPSR = (1 << SPI2X);
SPSR |= (1 << SPI2X);
else
SPSR &= ~(1 << SPI2X);
}
/** Sends and receives a byte through the SPI interface, blocking until the transfer is complete.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment