#include "terasic_includes.h" #include "usb_class.h" #ifdef DEBUG_USB_CLASS #define DEBUG_OUT(x) {printf("[USBCLASS]"); printf x;} #define DEBUG_ERR(x) {printf("[USBCLASS_ERR]"); printf x;} #else #define DEBUG_OUT(x) #define DEBUG_ERR(x) #endif //DEBUG_USB_CLASS static USB_DEVICE_TYPE classGetDeviceType(alt_u8 *pConfigStart, alt_u16 ConfigLen); USB_DEVICE_TYPE USBCLASS_GetDeviceType(HUB_HANDLE hHub, alt_u8 Port, USB_SPEED Speed){ HUB_DEVICE *pHub = (HUB_DEVICE *)hHub; USB_DEVICE_TYPE DeviceType = USB_DEVICE_TYPE_UNKNOWN; USB_DEVICE UsbDevice; bool bSuccess; USB_DEVICE_DESCRIPTOR DeviceDesc; memset(&UsbDevice, 0, sizeof(UsbDevice)); UsbDevice.HubAddr = pHub->UsbDevice.Addr; UsbDevice.Port = Port; UsbDevice.Addr = 0; UsbDevice.Speed = Speed; UsbDevice.EpIn[0].Type = EPType_CONTROL; UsbDevice.EpIn[0].MaxPacketSize = 8; UsbDevice.EpOut[0].Type = EPType_CONTROL; UsbDevice.EpOut[0].MaxPacketSize = 8; // get device descriptor at address 0, determine the max packatge size of control endpoint bSuccess = USB_GetDescriptor(&UsbDevice, USBDT_DEVICE, (alt_u8 *)&DeviceDesc, 8); if (bSuccess){ UsbDevice.EpIn[0].MaxPacketSize = DeviceDesc.bMaxPacketSize0; UsbDevice.EpOut[0].MaxPacketSize = DeviceDesc.bMaxPacketSize0; } if (bSuccess){ // get device descriptor with new max package size bSuccess = USB_GetDescriptor(&UsbDevice, USBDT_DEVICE, (alt_u8 *)&DeviceDesc, sizeof(DeviceDesc)); if (bSuccess && DeviceDesc.bDeviceClass == USBCS_DEVICE && DeviceDesc.bDeviceSubClass == 0 && DeviceDesc.bDeviceProtocol == 0){ // could be mouse, check interface protocol to determine the type //DeviceType = USB_DEVICE_TYPE_MOUSE; }else{ bSuccess = FALSE; } } // determine device type by interface attribyte if (bSuccess){ // get configuration descriptor to determine other descriptor size alt_u8 szBuf[8]; bSuccess = USB_GetDescriptor(&UsbDevice, USBDT_CONFIGURATION, szBuf, 8); if (bSuccess){ USB_CONFIG_DESCRIPTOR *pConfig; pConfig = (USB_CONFIG_DESCRIPTOR *)szBuf; if (pConfig->bLength != 0x09 || pConfig->bDescriptorType != USBDT_CONFIGURATION){ DEBUG_OUT(("Invalid Config Descriptor\n")); }else{ // get full configuration descriptor, including interface descriptor alt_u8 *pBuf; alt_u16 ConfigLen; ConfigLen = pConfig->wTotalLength; pBuf = malloc(ConfigLen); bSuccess = USB_GetDescriptor(&UsbDevice, USBDT_CONFIGURATION, pBuf, ConfigLen); if (!bSuccess){ DEBUG_OUT(("Get Config Descriptor fail (len=%d)\n", ConfigLen)); }else{ // check whether it is Bulk-Only Protocol DeviceType = classGetDeviceType(pBuf, ConfigLen); } free(pBuf); } }else{ DEBUG_OUT(("Get Config Descriptor fail (len=%d)\n", 8)); } } return DeviceType; } void USBCLASS_GetDeviceTypeName(USB_DEVICE_TYPE DeviceType, char *pBuffer, int nBufferLen){ switch(DeviceType){ case USB_DEVICE_TYPE_MOUSE: strcpy(pBuffer, "USB-Mouse"); break; case USB_DEVICE_TYPE_DISK: strcpy(pBuffer, "USB-Disk"); break; case USB_DEVICE_TYPE_UNKNOWN: strcpy(pBuffer, "USB-Unknown"); break; }// switch } static USB_DEVICE_TYPE classGetDeviceType(alt_u8 *pConfigStart, alt_u16 ConfigLen){ USB_DEVICE_TYPE DeviceType = USB_DEVICE_TYPE_UNKNOWN; USB_CONFIG_DESCRIPTOR *pConfig; USB_INTERFACE_DESCRIPTOR *pInterface; pConfig = (USB_CONFIG_DESCRIPTOR *)pConfigStart; if (pConfig->bLength != 0x09){ DEBUG_OUT(("Invalid Config Length\n")); return DeviceType; } if (pConfig->bDescriptorType != USBDT_CONFIGURATION){ DEBUG_OUT(("Invalid Config Type\n")); return DeviceType; } if (ConfigLen < 18){ DEBUG_OUT(("Invalid Config Length\n")); return DeviceType; } pInterface = (USB_INTERFACE_DESCRIPTOR *)(pConfigStart + 9); if (pInterface->bLength != 0x09){ DEBUG_OUT(("Invalid Interface Length\n")); return DeviceType; } if (pInterface->bDescriptorType != 0x04){ DEBUG_OUT(("Invalid Interface Descriptor Type\n")); return DeviceType; } if (pInterface->bInterfaceClass == USBCS_HID && pInterface->bInterfaceSubClass == 0x01 && pInterface->bInterfaceProtocol == 0x02 && pInterface->bNumEndpoints >= 1 ){ DEBUG_OUT(("This is a HID Mouse.\n")); DeviceType = USB_DEVICE_TYPE_MOUSE; return DeviceType; } if (pInterface->bInterfaceClass == USBCS_MASS_STORAGE && pInterface->bInterfaceSubClass == 0x06 && pInterface->bInterfaceProtocol == 0x50 && pInterface->bNumEndpoints >= 2){ DEBUG_OUT(("This is a bulk-only Storage\n")); DeviceType = USB_DEVICE_TYPE_DISK; return DeviceType; } return DeviceType; }