/**************************************************************************//** * @brief main - the entrypoint after reset. *****************************************************************************/ int main(void) { int connectionResult; USBH_Init_TypeDef is = USBH_INIT_DEFAULT; BSP_Init(BSP_INIT_DEFAULT); /* Initialize DK board register access */ /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO); ConsoleDebugInit(); /* Initialize DK UART port. */ printf("\n\nEFM32 USB Host device enumeration example.\n"); USBH_Init(&is); /* Initialize USB HOST stack */ for (;;) { /* Wait for device connection */ printf("\nWaiting for USB device plug-in...\n"); /* Wait for maximum 10 seconds. */ connectionResult = USBH_WaitForDeviceConnectionB( tmpBuf, 10 ); if ( connectionResult == USB_STATUS_OK ) { printf("\nA device was attached...\n"); if (USBH_QueryDeviceB(tmpBuf, sizeof(tmpBuf), USBH_GetPortSpeed()) == USB_STATUS_OK) { USBH_InitDeviceData(&device, tmpBuf, NULL, 0, USBH_GetPortSpeed()); printf( "\nDevice VID/PID is 0x%04X/0x%04X, device bus speed is %s", device.devDesc.idVendor, device.devDesc.idProduct, USBH_GetPortSpeed() == PORT_FULL_SPEED ? "FULL" : "LOW" ); GetDeviceStrings(); } else { printf("\nDevice enumeration failure, please unplug device...\n"); } while ( USBH_DeviceConnected() ){} printf("\n\nDevice removal detected..."); } else if ( connectionResult == USB_STATUS_DEVICE_MALFUNCTION ) { printf("\nA malfunctioning device was attached, please remove...\n"); } else if ( connectionResult == USB_STATUS_PORT_OVERCURRENT ) { printf( "\nVBUS overcurrent condition, please remove device.\n" ); } else if ( connectionResult == USB_STATUS_TIMEOUT ) { printf("\nNo device was attached...\n"); } USBH_Stop(); } }
/***************************************************************************//** * @brief * Initialize an USB connected Mass Storage Device. * Checks if the device is a valid MSD device. Will perform all * necessary MSD initialization. * * @note * This function assumes that prior calls to USBH_Init() and * USBH_WaitForDeviceConnectionB() have been performed. * The contents of the usbDeviceInfo data buffer will be overwritten. * * @param[in] usbDeviceInfo * Pointer to USB enumeration information. usbDeviceInfo must have been * initialized by a prior call to USBH_WaitForDeviceConnectionB(). * * @param[in] usbDeviceInfoSize * The size of the usbDeviceInfo data buffer. * * @return * Returns true on success, false otherwise. ******************************************************************************/ bool MSDH_Init(uint8_t *usbDeviceInfo, int usbDeviceInfoSize) { EFM32_ALIGN(4) MSDSCSI_InquiryData_TypeDef inquiryData __attribute__ ((aligned(4))); EFM32_ALIGN(4) MSDSCSI_ReadCapacityData_TypeDef capacityData __attribute__ ((aligned(4))); EFM32_ALIGN(4) MSDSCSI_RequestSenseData_TypeDef reqSenseData __attribute__ ((aligned(4))); bool ready; int result, i; /* Read all device descriptors. */ if (USBH_QueryDeviceB(usbDeviceInfo, usbDeviceInfoSize, USBH_GetPortSpeed()) != USB_STATUS_OK) return false; /* Check if a valid MSD device (will activate device if OK). */ if (!QualifyDevice(usbDeviceInfo)) return false; /* Initialize MSD SCSI module. */ if (!MSDSCSI_Init(BULK_OUT, BULK_IN)) return false; /* Do a SCSI Inquiry to get some info from the device. */ if (!MSDSCSI_Inquiry(&inquiryData)) { /* Do one retry. */ if (!MSDSCSI_Inquiry(&inquiryData)) return false; } memcpy(usbDeviceInfo, &inquiryData.T10VendorId, sizeof(inquiryData.T10VendorId)); usbDeviceInfo[ sizeof(inquiryData.T10VendorId) ] = '\0'; USB_PRINTF("\nSCSI Inquiry Vendor ID string : \"%s\"", usbDeviceInfo); memcpy(usbDeviceInfo, &inquiryData.ProductId, sizeof(inquiryData.ProductId)); usbDeviceInfo[ sizeof(inquiryData.ProductId) ] = '\0'; USB_PRINTF("\nSCSI Inquiry Product ID string : \"%s\"", usbDeviceInfo); memcpy(usbDeviceInfo, &inquiryData.ProductRevisionLevel, sizeof(inquiryData.ProductRevisionLevel)); usbDeviceInfo[ sizeof(inquiryData.ProductRevisionLevel) ] = '\0'; USB_PRINTF("\nSCSI Inquiry Product Revision string : \"%s\"", usbDeviceInfo); /* Is it a block device ? */ if ((inquiryData.PeripheralQualifier != 0) || (inquiryData.PeripheralDeviceType != 0)) return false; /* Wait for upto 5 seconds for device to become ready. */ i = 0; do { result = MSDSCSI_RequestSense(&reqSenseData); ready = MSDSCSI_TestUnitReady(); if (!ready) USBTIMER_DelayMs(500); i++; } while (!ready && i < 10 && result); if (!result) { USB_PRINTF("\n\nSCSI Request Sense execution error"); return false; } if (!ready) { USB_PRINTF("\n\nMSD device not ready"); return false; } /* Get device capacity. */ if (!MSDSCSI_ReadCapacity(&capacityData)) { USB_PRINTF("\n\nSCSI Read Capacity execution error"); return false; } USB_PRINTF("\n\nSCSI Read Capacity LBA count : %ld = %ld MiB", capacityData.LogicalBlockAddress, (uint32_t) (((uint64_t)capacityData.LogicalBlockAddress * capacityData.LogicalBlockLength) / (1024 * 1024))); USB_PRINTF("\nSCSI Read Capacity LBA size : %ld\n\n", capacityData.LogicalBlockLength); return true; }