/**************************************************************************//** * @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 * Check if a device is a valid Mass Storage Device. * A valid device will be fully enumerated and activated. * * @param[in] buf * Enumeration data buffer. * * @return * Returns true if a valid MSD device, false otherwise. ******************************************************************************/ static bool QualifyDevice(uint8_t *buf) { int i; bool retVal = false; bool epIn = false, epOut = false; if ((USBH_QGetDeviceDescriptor(buf)->bDeviceClass == 0) && (USBH_QGetDeviceDescriptor(buf)->bDeviceSubClass == 0) && (USBH_QGetDeviceDescriptor(buf)->bDeviceProtocol == 0) && (USBH_QGetInterfaceDescriptor(buf, 0, 0)->bInterfaceClass == USB_CLASS_MSD) && (USBH_QGetInterfaceDescriptor(buf, 0, 0)->bInterfaceSubClass == USB_CLASS_MSD_SCSI_CMDSET) && (USBH_QGetInterfaceDescriptor(buf, 0, 0)->bInterfaceProtocol == USB_CLASS_MSD_BOT_TRANSPORT) && (USBH_QGetInterfaceDescriptor(buf, 0, 0)->bNumEndpoints >= 2)) { /* * OK so far, scan through endpoints and look for one BULK IN and * one BULK OUT endpoint. */ for (i = 0; i < USBH_QGetInterfaceDescriptor(buf, 0, 0)->bNumEndpoints; i++) { if (USBH_QGetEndpointDescriptor(buf, 0, 0, i)->bmAttributes == USB_EPTYPE_BULK) { if (USBH_QGetEndpointDescriptor(buf, 0, 0, i)->bEndpointAddress & USB_EP_DIR_IN) { if (!epIn) { epIn = true; epInIndex = i; } } else { if (!epOut) { epOut = true; epOutIndex = i; } } } /* Success ? */ if (epIn && epOut) break; } if ((epIn && epOut) && (epInIndex < 2) && (epOutIndex < 2)) { /* * Some MSD devices has more than the two required bulk endpoints. * We will only accept devices where the two bulk endpoints are * the two first endpoints within the interface. */ USB_PRINTF("\nThis is a valid MSD device."); retVal = true; } } if (retVal == false) { USBH_PrintDeviceDescriptor(USBH_QGetDeviceDescriptor(buf)); USBH_PrintConfigurationDescriptor(USBH_QGetConfigurationDescriptor(buf, 0), USB_CONFIG_DESCSIZE); USBH_PrintInterfaceDescriptor(USBH_QGetInterfaceDescriptor(buf, 0, 0)); for (i = 0; i < USBH_QGetInterfaceDescriptor(buf, 0, 0)->bNumEndpoints; i++) { USBH_PrintEndpointDescriptor(USBH_QGetEndpointDescriptor(buf, 0, 0, i)); } USB_PRINTF("\nThis is not a valid MSD device, review device descriptors."); } else { /* All set, activate the device. */ USBH_InitDeviceData(&device, buf, ep, 2, USBH_GetPortSpeed()); PrintDeviceStrings(buf); USBH_SetAddressB(&device, DEV_ADDR); USBH_SetConfigurationB(&device, device.confDesc.bConfigurationValue); /* Assign Host Channels to the endpoints */ USBH_AssignHostChannel(BULK_OUT, 2); USBH_AssignHostChannel(BULK_IN, 3); USB_PRINTF("\n\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"); } return retVal; }