// -------------------------------------------------------------------- // Copyright (c) 2007 by Terasic Technologies Inc. // -------------------------------------------------------------------- // // Permission: // // Terasic grants permission to use and modify this code for use // in synthesis for all Terasic Development Boards and Altera Development // Kits made by Terasic. Other use of this code, including the selling // ,duplication, or modification of any portion is strictly prohibited. // // Disclaimer: // // This VHDL/Verilog or C/C++ source code is intended as a design reference // which illustrates how these types of functions can be implemented. // It is the user's responsibility to verify their design for // consistency and functionality through the use of formal // verification methods. Terasic provides no warranty regarding the use // or functionality of this code. // // -------------------------------------------------------------------- // // Terasic Technologies Inc // 356 Fu-Shin E. Rd Sec. 1. JhuBei City, // HsinChu County, Taiwan // 302 // // web: http://www.terasic.com/ // email: support@terasic.com // // -------------------------------------------------------------------- #include "terasic_includes.h" #include "usb_mouse.h" #ifdef DEBUG_USB_MOUSE #define DEBUG_DATA(x) {printf x;} #define DEBUG_OUT(x) {printf("[USBMS]"); printf x;} #define DEBUG_ERR(x) {printf("[USBMS_ERR]"); printf x;} #else #define DEBUG_DATA(x) #define DEBUG_OUT(x) #define DEBUG_ERR(x) #endif //DEBUG_USB_MOUSE typedef struct{ // alt_u8 ConfigValue; alt_u8 Interval; // int-in alt_u8 IntInEp; alt_u8 IntInDataToggle; // int X,Y; // USB_DEVICE UsbDevice; }USBMOUSE_DRIVER; static bool msSetup(alt_u8 *szConfig, alt_u16 ConfigLen, USBMOUSE_DRIVER *pUsbMouse); USBMS_HANDLE USBMS_Open(HUB_HANDLE hHub, alt_u8 Port, USB_SPEED Speed, alt_u8 AssignedAddress){ HUB_DEVICE *pHub = (HUB_DEVICE *)hHub; bool bSuccess; USBMOUSE_DRIVER *pMouse; USB_DEVICE_DESCRIPTOR DeviceDesc; // alloc space pMouse = malloc(sizeof(USBMOUSE_DRIVER)); if (!pMouse) return pMouse; memset(pMouse, 0, sizeof(USBMOUSE_DRIVER)); pMouse->UsbDevice.HubAddr = pHub->UsbDevice.Addr; pMouse->UsbDevice.Port = Port; pMouse->UsbDevice.Addr = 0; pMouse->UsbDevice.Speed = Speed; pMouse->UsbDevice.EpIn[0].Type = EPType_CONTROL; pMouse->UsbDevice.EpIn[0].MaxPacketSize = 8; pMouse->UsbDevice.EpOut[0].Type = EPType_CONTROL; pMouse->UsbDevice.EpOut[0].MaxPacketSize = 8; // get descriptor at address 0 bSuccess = USB_GetDescriptor(&pMouse->UsbDevice, USBDT_DEVICE, (alt_u8 *)&DeviceDesc, 8); if (bSuccess){ pMouse->UsbDevice.EpIn[0].MaxPacketSize = DeviceDesc.bMaxPacketSize0; pMouse->UsbDevice.EpOut[0].MaxPacketSize = DeviceDesc.bMaxPacketSize0; } // set address if (bSuccess){ bSuccess = USB_SetDeviceAddres(&pMouse->UsbDevice, AssignedAddress); if (bSuccess) pMouse->UsbDevice.Addr = AssignedAddress; } // get descriptor at new address bSuccess = USB_GetDescriptor(&pMouse->UsbDevice, USBDT_DEVICE, (alt_u8 *)&DeviceDesc, sizeof(DeviceDesc)); if (bSuccess && DeviceDesc.bDeviceClass != USBCS_DEVICE){ DEBUG_OUT(("Not a usb mouse\n")); bSuccess = FALSE; } // get configuration & build mouse driver content if (bSuccess){ USB_CONFIG_DESCRIPTOR Config; bSuccess = USB_GetDescriptor(&pMouse->UsbDevice, USBDT_CONFIGURATION, (alt_u8 *)&Config, sizeof(Config)); if (bSuccess && Config.bLength == sizeof(Config) && Config.bDescriptorType == USBDT_CONFIGURATION){ alt_u8 ConfigLen = Config.wTotalLength; alt_u8 *szConfig; szConfig = malloc(ConfigLen); if (szConfig){ bSuccess = USB_GetDescriptor(&pMouse->UsbDevice, USBDT_CONFIGURATION, (alt_u8 *)szConfig, ConfigLen); if (bSuccess){ bSuccess = msSetup(szConfig, ConfigLen, pMouse); if (bSuccess){ const alt_u8 ConfigValue = pMouse->ConfigValue;//pConfig->bConfigurationValue; bSuccess = USB_SetConfig(&pMouse->UsbDevice, ConfigValue); } } free(szConfig); }else{ DEBUG_ERR(("Alloc space for configuration fail.\n")); bSuccess = FALSE; } } } if (!bSuccess){ free(pMouse); pMouse = 0; } return pMouse; } void USBMS_Close(USBMS_HANDLE hMouse){ USBMOUSE_DRIVER *pMouse = (USBMOUSE_DRIVER *)hMouse; if (pMouse) free(pMouse); } bool USBMS_GetStatus(USBMS_HANDLE hMouse, int *px, int *py, int *pstatus){ USBMOUSE_DRIVER *pMouse = (USBMOUSE_DRIVER *)hMouse; int X, Y; bool bSuccess = FALSE; PTD_RESULT PtdResult; alt_8 szStatus[4]; alt_u8 EndPt = pMouse->IntInEp;// | 0x80; //1 | 0x10; alt_8 dx, dy; alt_u16 InLen; X = pMouse->X; Y = pMouse->Y; // get mouse status, read 4 byte // status = byte[0] & 0x0F // dx = byte[1] & 0xFF // dy = byte[2] & 0xFF PtdResult = PORT_IntIn(&pMouse->UsbDevice, szStatus, sizeof(szStatus), EndPt, pMouse->IntInDataToggle, &InLen); if (PtdResult == PTD_RESULT_SUCCESS){ if (InLen == sizeof(szStatus)){ dx = szStatus[1]; dy = szStatus[2]; X += dx; Y += dy; *px = X; *py = Y; *pstatus = szStatus[0] & 0xFF; if (X < 0) X = 0; if (Y < 0) Y = 0; pMouse->X = X; pMouse->Y = Y; pMouse->IntInDataToggle++; //DEBUG_OUT(("Status: %X, dx=%d, dy=%d, X=%d, Y=%d\n", szStatus[0] & 0x0F, (int)dx,(int)dy, X, Y )); bSuccess = TRUE; }else{ //DEBUG_OUT(("Invalid input len=%d\n", InLen)); } }else{ //DEBUG_DATA((".")); //DEBUG_OUT(("Read Int-In fail\n")); } return bSuccess; } #if 0 void USB_MouseOpen(HUB_HANDLE hHub, alt_u8 Port, USB_SPEED Speed, alt_u8 AssignedAddress){ HUB_DEVICE *pHub = (HUB_DEVICE *)hHub; int X=0,Y=0; bool bSuccess; USBMOUSE_DRIVER UsbMouse; USB_DEVICE_DESCRIPTOR DeviceDesc; memset(&UsbMouse, 0, sizeof(UsbMouse)); UsbMouse.UsbDevice.HubAddr = pHub->UsbDevice.Addr; UsbMouse.UsbDevice.Port = Port; UsbMouse.UsbDevice.Addr = 0; UsbMouse.UsbDevice.Speed = Speed; UsbMouse.UsbDevice.EpIn[0].Type = EPType_CONTROL; UsbMouse.UsbDevice.EpIn[0].MaxPacketSize = 8; UsbMouse.UsbDevice.EpOut[0].Type = EPType_CONTROL; UsbMouse.UsbDevice.EpOut[0].MaxPacketSize = 8; // get descriptor at address 0 bSuccess = USB_GetDescriptor(&UsbMouse.UsbDevice, USBDT_DEVICE, (alt_u8 *)&DeviceDesc, 8); if (bSuccess){ UsbMouse.UsbDevice.EpIn[0].MaxPacketSize = DeviceDesc.bMaxPacketSize0; UsbMouse.UsbDevice.EpOut[0].MaxPacketSize = DeviceDesc.bMaxPacketSize0; } // set address if (bSuccess){ bSuccess = USB_SetDeviceAddres(&UsbMouse.UsbDevice, AssignedAddress); if (bSuccess) UsbMouse.UsbDevice.Addr = AssignedAddress; } // get descriptor at new address bSuccess = USB_GetDescriptor(&UsbMouse.UsbDevice, USBDT_DEVICE, (alt_u8 *)&DeviceDesc, sizeof(DeviceDesc)); if (bSuccess && DeviceDesc.bDeviceClass != USBCS_DEVICE){ DEBUG_OUT(("Not a usb mouse\n")); bSuccess = FALSE; } // get configuration if (bSuccess){ USB_CONFIG_DESCRIPTOR Config; bSuccess = USB_GetDescriptor(&UsbMouse.UsbDevice, USBDT_CONFIGURATION, (alt_u8 *)&Config, sizeof(Config)); if (bSuccess && Config.bLength == sizeof(Config) && Config.bDescriptorType == USBDT_CONFIGURATION){ alt_u8 ConfigLen = Config.wTotalLength; alt_u8 *szConfig; szConfig = malloc(ConfigLen); if (szConfig){ bSuccess = USB_GetDescriptor(&UsbMouse.UsbDevice, USBDT_CONFIGURATION, (alt_u8 *)szConfig, ConfigLen); if (bSuccess){ bSuccess = msSetup(szConfig, ConfigLen, &UsbMouse); if (bSuccess){ const alt_u8 ConfigValue = UsbMouse.ConfigValue;//pConfig->bConfigurationValue; bSuccess = USB_SetConfig(&UsbMouse.UsbDevice, ConfigValue); } } free(szConfig); }else{ DEBUG_ERR(("Alloc space for configuration fail.\n")); } } } if (bSuccess){ int i; alt_u8 szData[] = {0x81, 0x06, 0x00, 0x22, 0x00, 0x00, 0x74, 0x00}; alt_u8 szRead[52]; if (USB_ControlRequest(&UsbMouse.UsbDevice, szData, szRead, sizeof(szRead))){ DEBUG_DATA(("--->\n")); for(i=0;ibLength != 0x09){ DEBUG_OUT(("Invalid Config Length\n")); return FALSE; } if (pConfig->bDescriptorType != USBDT_CONFIGURATION){ DEBUG_OUT(("Invalid Config Type\n")); return FALSE; } if (ConfigLen < 18){ DEBUG_OUT(("Invalid Config Length\n")); return FALSE; } pUsbMouse->ConfigValue = pConfig->bConfigurationValue; // interface descriptor pInterface = (USB_INTERFACE_DESCRIPTOR *) (szConfig + 9); if (pInterface->bLength != 0x09){ DEBUG_OUT(("Invalid Interface Length\n")); return FALSE; } if (pInterface->bInterfaceClass != USBCS_HID || pInterface->bInterfaceSubClass != 0x01 || pInterface->bInterfaceProtocol != 0x02 || pInterface->bNumEndpoints < 1 ){ DEBUG_OUT(("This is not a HID Mouse.\n")); return FALSE; } // HID descriptor pHID = (USB_HID_DESCRIPTOR *) (szConfig + 18); if (pHID->bLength != 0x09){ DEBUG_OUT(("Invalid HID Descriptor Length\n")); return FALSE; } if (pHID->bDescriptorType != 0x21){ DEBUG_OUT(("Invalid HID Descriptor Type\n")); return FALSE; } if (pHID->bNumDescriptors != 1 || pHID->iDescriptorType != 0x22){ DEBUG_OUT(("This is not a HID Mouse.\n")); return FALSE; } // Endpoint descriptor pEndpoint = (USB_ENDPOINT_DESCRIPTOR *) (szConfig + 27); if (pEndpoint->bLength != 0x07){ DEBUG_OUT(("Invalid Endpoint Length\n")); return FALSE; } if (pEndpoint->bDescriptorType != 0x05){ DEBUG_OUT(("Invalid Endpoint Descriptor Type\n")); return FALSE; } if (pEndpoint->bmAttributes != 0x03 || ((pEndpoint->bEndpointAddress & 0x80) == 0)){ DEBUG_OUT(("No an IN interrupt endpoint\n")); return FALSE; } pUsbMouse->IntInEp = pEndpoint->bEndpointAddress & 0x7F; pUsbMouse->Interval = pEndpoint->bInterval; pUsbMouse->UsbDevice.EpIn[pUsbMouse->IntInEp].MaxPacketSize = pEndpoint->wMaxPacketSize; pUsbMouse->UsbDevice.EpIn[pUsbMouse->IntInEp].Type = EPType_INTERRUPT; pUsbMouse->IntInDataToggle = 0; return TRUE; }