MassStorageHost demo now retrieves Inquiry data from the device during enumeration, and prints the device's Vendor and Product IDs.
This commit is contained in:
		
							parent
							
								
									bb23e55f11
								
							
						
					
					
						commit
						64937a6206
					
				
					 3 changed files with 115 additions and 2 deletions
				
			
		| 
						 | 
				
			
			@ -301,6 +301,69 @@ uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex)
 | 
			
		|||
	return ErrorCode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Issues a SCSI Inquiry command to the attached device, to determine the device's information. This
 | 
			
		||||
 *  gives information on the device's capabilities.
 | 
			
		||||
 *
 | 
			
		||||
 *  \param LUNIndex    Index of the LUN inside the device the command is being addressed to
 | 
			
		||||
 *  \param InquiryPtr  Pointer to the inquiry data structure where the inquiry data from the device is to be stored
 | 
			
		||||
 *
 | 
			
		||||
 *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum
 | 
			
		||||
 */
 | 
			
		||||
uint8_t MassStore_Inquiry(const uint8_t LUNIndex, const SCSI_Inquiry_Response_t* const InquiryPtr)
 | 
			
		||||
{
 | 
			
		||||
	uint8_t ReturnCode = PIPE_RWSTREAM_NoError;
 | 
			
		||||
 | 
			
		||||
	/* Create a CBW with a SCSI command to issue INQUIRY command */
 | 
			
		||||
	SCSICommandBlock = (CommandBlockWrapper_t)
 | 
			
		||||
		{
 | 
			
		||||
			.Header =
 | 
			
		||||
				{
 | 
			
		||||
					.Signature          = CBW_SIGNATURE,
 | 
			
		||||
					.Tag                = MassStore_Tag,
 | 
			
		||||
					.DataTransferLength = sizeof(SCSI_Inquiry_Response_t),
 | 
			
		||||
					.Flags              = COMMAND_DIRECTION_DATA_IN,
 | 
			
		||||
					.LUN                = LUNIndex,
 | 
			
		||||
					.SCSICommandLength  = 6
 | 
			
		||||
				},
 | 
			
		||||
					
 | 
			
		||||
			.SCSICommandData =
 | 
			
		||||
				{
 | 
			
		||||
					SCSI_CMD_INQUIRY,
 | 
			
		||||
					0x00,                   // Reserved
 | 
			
		||||
					0x00,                   // Reserved
 | 
			
		||||
					0x00,                   // Reserved
 | 
			
		||||
					sizeof(SCSI_Inquiry_Response_t), // Allocation Length
 | 
			
		||||
					0x00                    // Unused (control)
 | 
			
		||||
				}
 | 
			
		||||
		};
 | 
			
		||||
	
 | 
			
		||||
	/* Send SCSI command to the attached device */
 | 
			
		||||
	MassStore_SendCommand();
 | 
			
		||||
 | 
			
		||||
	/* Wait until data received from the device */
 | 
			
		||||
	if ((ReturnCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)
 | 
			
		||||
	{
 | 
			
		||||
		Pipe_Freeze();
 | 
			
		||||
		return ReturnCode;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Read the returned sense data into the buffer */
 | 
			
		||||
	if ((ReturnCode = MassStore_SendReceiveData((uint8_t*)InquiryPtr)) != PIPE_RWSTREAM_NoError)
 | 
			
		||||
	{
 | 
			
		||||
		Pipe_Freeze();
 | 
			
		||||
		return ReturnCode;
 | 
			
		||||
	}	
 | 
			
		||||
	
 | 
			
		||||
	/* Read in the returned CSW from the device */
 | 
			
		||||
	if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)
 | 
			
		||||
	{
 | 
			
		||||
		Pipe_Freeze();
 | 
			
		||||
		return ReturnCode;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	return PIPE_RWSTREAM_NoError;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Issues a SCSI Request Sense command to the attached device, to determine the current SCSI sense information. This
 | 
			
		||||
 *  gives error codes for the last issued SCSI command to the device.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,6 +128,43 @@
 | 
			
		|||
			uint8_t      SenseKeySpecific[3];
 | 
			
		||||
		} SCSI_Request_Sense_Response_t;
 | 
			
		||||
 | 
			
		||||
		/** Type define for a SCSI Inquiry structure. Structures of this type are filled out by the
 | 
			
		||||
		 *  device via the MassStore_Inquiry() function, retrieving the attached device's information.
 | 
			
		||||
		 *  For details of the structure contents, refer to the SCSI specifications.
 | 
			
		||||
		 */
 | 
			
		||||
		typedef struct
 | 
			
		||||
		{
 | 
			
		||||
			unsigned char DeviceType          : 5;
 | 
			
		||||
			unsigned char PeripheralQualifier : 3;
 | 
			
		||||
			
 | 
			
		||||
			unsigned char _RESERVED1          : 7;
 | 
			
		||||
			unsigned char Removable           : 1;
 | 
			
		||||
			
 | 
			
		||||
			uint8_t      Version;
 | 
			
		||||
			
 | 
			
		||||
			unsigned char ResponseDataFormat  : 4;
 | 
			
		||||
			unsigned char _RESERVED2          : 1;
 | 
			
		||||
			unsigned char NormACA             : 1;
 | 
			
		||||
			unsigned char TrmTsk              : 1;
 | 
			
		||||
			unsigned char AERC                : 1;
 | 
			
		||||
 | 
			
		||||
			uint8_t      AdditionalLength;
 | 
			
		||||
			uint8_t      _RESERVED3[2];
 | 
			
		||||
 | 
			
		||||
			unsigned char SoftReset           : 1;
 | 
			
		||||
			unsigned char CmdQue              : 1;
 | 
			
		||||
			unsigned char _RESERVED4          : 1;
 | 
			
		||||
			unsigned char Linked              : 1;
 | 
			
		||||
			unsigned char Sync                : 1;
 | 
			
		||||
			unsigned char WideBus16Bit        : 1;
 | 
			
		||||
			unsigned char WideBus32Bit        : 1;
 | 
			
		||||
			unsigned char RelAddr             : 1;
 | 
			
		||||
			
 | 
			
		||||
			uint8_t      VendorID[8];
 | 
			
		||||
			uint8_t      ProductID[16];
 | 
			
		||||
			uint8_t      RevisionID[4];
 | 
			
		||||
		} SCSI_Inquiry_Response_t;
 | 
			
		||||
		
 | 
			
		||||
		/** SCSI capacity structure, to hold the total capacity of the device in both the number
 | 
			
		||||
		 *  of blocks in the current LUN, and the size of each block. This structure is filled by
 | 
			
		||||
		 *  the device when the MassStore_ReadCapacity() function is called.
 | 
			
		||||
| 
						 | 
				
			
			@ -162,6 +199,8 @@
 | 
			
		|||
		uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex);
 | 
			
		||||
		uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr)
 | 
			
		||||
		                               ATTR_NON_NULL_PTR_ARG(2);
 | 
			
		||||
		uint8_t MassStore_Inquiry(const uint8_t LUNIndex, const SCSI_Inquiry_Response_t* const InquiryPtr)
 | 
			
		||||
		                               ATTR_NON_NULL_PTR_ARG(2);
 | 
			
		||||
		uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,
 | 
			
		||||
		                                  const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5);
 | 
			
		||||
		uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -191,7 +191,7 @@ void MassStorage_Task(void)
 | 
			
		|||
			}
 | 
			
		||||
			
 | 
			
		||||
			/* Print number of LUNs detected in the attached device */
 | 
			
		||||
			printf_P(PSTR("Total LUNs: %d.\r\n"), (MassStore_MaxLUNIndex + 1));
 | 
			
		||||
			printf_P(PSTR("Total LUNs: %d - Using first LUN in device.\r\n"), (MassStore_MaxLUNIndex + 1));
 | 
			
		||||
			
 | 
			
		||||
			/* Reset the Mass Storage device interface, ready for use */
 | 
			
		||||
			if ((ErrorCode = MassStore_MassStorageReset()) != HOST_SENDCONTROL_Successful)
 | 
			
		||||
| 
						 | 
				
			
			@ -216,9 +216,20 @@ void MassStorage_Task(void)
 | 
			
		|||
				break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			puts_P(PSTR("Waiting until ready.."));
 | 
			
		||||
			/* Get inquiry data from the device */
 | 
			
		||||
			SCSI_Inquiry_Response_t InquiryData;
 | 
			
		||||
			if (((ErrorCode = MassStore_Inquiry(0, &InquiryData)) != 0) || (SCSICommandStatus.Status != Command_Pass))
 | 
			
		||||
			{
 | 
			
		||||
				ShowDiskReadError(PSTR("Inquiry"), (SCSICommandStatus.Status != Command_Pass), ErrorCode);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			/* Print vendor and product names of attached device */
 | 
			
		||||
			printf_P(PSTR("Vendor: %s, Product: %s\r\n"), InquiryData.VendorID, InquiryData.ProductID);
 | 
			
		||||
						
 | 
			
		||||
			/* Wait until disk ready */
 | 
			
		||||
			puts_P(PSTR("Waiting until ready.."));
 | 
			
		||||
 | 
			
		||||
			do
 | 
			
		||||
			{
 | 
			
		||||
				Serial_TxByte('.');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue