25 #define BULK_OUT &ep[ epOutIndex ]
26 #define BULK_IN &ep[ epInIndex ]
28 static void PrintDeviceStrings(uint8_t *buf);
29 static bool QualifyDevice(uint8_t *buf);
31 static USBH_Device_TypeDef device;
32 static USBH_Ep_TypeDef ep[ 2 ];
33 static int epOutIndex;
59 bool MSDH_Init(uint8_t *usbDeviceInfo,
int usbDeviceInfoSize)
74 if (USBH_QueryDeviceB(usbDeviceInfo, usbDeviceInfoSize, USBH_GetPortSpeed())
77 USB_PRINTF(
"\nUSB descriptor retrieval failed.");
82 if (!QualifyDevice(usbDeviceInfo))
88 USB_PRINTF(
"\nMSD BOT initialization failed.");
103 memcpy(usbDeviceInfo, &inquiryData.T10VendorId,
sizeof(inquiryData.T10VendorId));
104 usbDeviceInfo[
sizeof(inquiryData.T10VendorId) ] =
'\0';
105 USB_PRINTF(
"\nSCSI Inquiry Vendor ID string : \"%s\"", usbDeviceInfo);
107 memcpy(usbDeviceInfo, &inquiryData.ProductId,
sizeof(inquiryData.ProductId));
108 usbDeviceInfo[
sizeof(inquiryData.ProductId) ] =
'\0';
109 USB_PRINTF(
"\nSCSI Inquiry Product ID string : \"%s\"", usbDeviceInfo);
111 memcpy(usbDeviceInfo, &inquiryData.ProductRevisionLevel,
sizeof(inquiryData.ProductRevisionLevel));
112 usbDeviceInfo[
sizeof(inquiryData.ProductRevisionLevel) ] =
'\0';
113 USB_PRINTF(
"\nSCSI Inquiry Product Revision string : \"%s\"", usbDeviceInfo);
116 if ((inquiryData.PeripheralQualifier != 0) ||
117 (inquiryData.PeripheralDeviceType != 0))
129 }
while (!ready && i < 10 && result);
133 USB_PRINTF(
"\n\nSCSI Request Sense execution error");
146 USB_PRINTF(
"\n\nSCSI Read Capacity execution error");
150 USB_PRINTF(
"\n\nSCSI Read Capacity LBA count : %ld = %ld MiB",
151 capacityData.LogicalBlockAddress,
153 (((uint64_t)capacityData.LogicalBlockAddress
154 * capacityData.LogicalBlockLength) / (1024 * 1024)));
155 USB_PRINTF(
"\nSCSI Read Capacity LBA size : %ld\n\n",
156 capacityData.LogicalBlockLength);
179 *sectorCount = capacityData.LogicalBlockAddress;
202 *sectorSize = (uint16_t) capacityData.LogicalBlockLength;
228 *blockSize = capacityData.LogicalBlockLength;
288 static bool QualifyDevice(uint8_t *buf)
292 bool epIn =
false, epOut =
false;
294 if ((USBH_QGetDeviceDescriptor(buf)->bDeviceClass == 0) &&
295 (USBH_QGetDeviceDescriptor(buf)->bDeviceSubClass == 0) &&
296 (USBH_QGetDeviceDescriptor(buf)->bDeviceProtocol == 0) &&
297 (USBH_QGetInterfaceDescriptor(buf, 0, 0)->bInterfaceClass ==
USB_CLASS_MSD) &&
300 (USBH_QGetInterfaceDescriptor(buf, 0, 0)->bNumEndpoints >= 2))
306 for (i = 0; i < USBH_QGetInterfaceDescriptor(buf, 0, 0)->bNumEndpoints; i++)
308 if (USBH_QGetEndpointDescriptor(buf, 0, 0, i)->bmAttributes ==
USB_EPTYPE_BULK)
310 if (USBH_QGetEndpointDescriptor(buf, 0, 0, i)->bEndpointAddress &
USB_EP_DIR_IN)
333 if ((epIn && epOut) && (epInIndex < 2) && (epOutIndex < 2))
347 USBH_PrintDeviceDescriptor(USBH_QGetDeviceDescriptor(buf));
348 USBH_PrintConfigurationDescriptor(USBH_QGetConfigurationDescriptor(buf, 0),
USB_CONFIG_DESCSIZE);
349 USBH_PrintInterfaceDescriptor(USBH_QGetInterfaceDescriptor(buf, 0, 0));
351 for (i = 0; i < USBH_QGetInterfaceDescriptor(buf, 0, 0)->bNumEndpoints; i++)
353 USBH_PrintEndpointDescriptor(USBH_QGetEndpointDescriptor(buf, 0, 0, i));
355 USB_PRINTF(
"\nThis is not a valid MSD device, review device descriptors.");
361 USBH_InitDeviceData(&device, buf, ep, 2, USBH_GetPortSpeed());
362 PrintDeviceStrings(buf);
363 USBH_SetAddressB(&device, DEV_ADDR);
364 USBH_SetConfigurationB(&device, device.confDesc.bConfigurationValue);
367 USBH_AssignHostChannel(BULK_OUT, 2);
368 USBH_AssignHostChannel(BULK_IN, 3);
370 USB_PRINTF(
"\n\nDevice VID/PID is 0x%04X/0x%04X, device bus speed is %s",
371 device.devDesc.idVendor, device.devDesc.idProduct,
385 static void PrintDeviceStrings(uint8_t *buf)
389 if (device.devDesc.iManufacturer)
391 USBH_GetStringB(&device, buf, 255, device.devDesc.iManufacturer,
393 USBH_PrintString(
"\n\niManufacturer = \"",
401 if (device.devDesc.iProduct)
403 USBH_GetStringB(&device, buf, 255, device.devDesc.iProduct,
405 USBH_PrintString(
"\niProduct = \"",
413 if (device.devDesc.iSerialNumber)
415 USBH_GetStringB(&device, buf, 255, device.devDesc.iSerialNumber,
417 USBH_PrintString(
"\niSerialNumber = \"",
bool MSDSCSI_TestUnitReady(void)
Issue a SCSI Test Unit Ready command.
SCSI Inquiry response data typedef.
bool MSDH_WriteSectors(uint32_t lba, uint16_t sectors, const void *data)
Write sectors to device.
SCSI Request Sense response data typedef.
int USB_PRINTF(const char *format,...)
Transmit "printf" formated data on the debug serial port.
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
bool MSDH_ReadSectors(uint32_t lba, uint16_t sectors, void *data)
Read sectors from device.
SCSI Read Capacity response data typedef.
bool MSDH_GetBlockSize(uint32_t *blockSize)
Get blocksize from the device.
#define USB_CLASS_MSD_BOT_TRANSPORT
bool MSDSCSI_Write10(uint32_t lba, uint16_t sectors, const void *data)
Perform a SCSI Write(10) command.
void USBTIMER_DelayMs(uint32_t msec)
Active wait millisecond delay function. Can also be used inside interrupt handlers.
bool MSDH_GetSectorSize(uint16_t *sectorSize)
Get sectorsize from the device.
SCSI interface for Mass Storage Devices (MSD).
#define USB_CONFIG_DESCSIZE
bool MSDH_Init(uint8_t *usbDeviceInfo, int usbDeviceInfoSize)
Initialize an USB connected Mass Storage Device. Checks if the device is a valid MSD device...
USB protocol stack library API for EFM32/EZR32.
#define USB_CLASS_MSD_SCSI_CMDSET
bool MSDSCSI_RequestSense(MSDSCSI_RequestSenseData_TypeDef *data)
Issue a SCSI Request Sense command.
bool MSDH_GetSectorCount(uint32_t *sectorCount)
Get sectorcount from the device.
bool MSDSCSI_Init(USBH_Ep_TypeDef *out, USBH_Ep_TypeDef *in)
MSDSCSI module initialization.
bool MSDSCSI_Read10(uint32_t lba, uint16_t sectors, void *data)
Issue a SCSI Read(10) command.
bool MSDSCSI_ReadCapacity(MSDSCSI_ReadCapacityData_TypeDef *data)
Issue a SCSI Read Capacity command.
bool MSDSCSI_Inquiry(MSDSCSI_InquiryData_TypeDef *data)
Issue a SCSI Inquiry command.