|
public class USBMouse extends USBDevice { |
|
|
|
private boolean isLMBPressed; |
|
private boolean isRMBPressed; |
|
private EndpointBuffer mouseEndp; |
|
|
|
public USBMouse(String mac) { |
|
super(mac); |
|
//setup descriptors |
|
//Vendor ID, Product ID, Endpoint 0 size |
|
DeviceDescriptor devDesc = new DeviceDescriptor(0x0483, 0xF772, 64); |
|
//Number of interfaces, Attribures: bus powered, required current: 100mA |
|
ConfigurationDescriptor confDesc = new ConfigurationDescriptor(1, 0xE0, 100); |
|
//interface number, Alternate settings, Number of endpoints: 1 (EP1IN) |
|
InterfaceDescriptor intDesc = new InterfaceDescriptor(0, 0, 1); |
|
HIDDescriptor hidDesc = new HIDDescriptor(); |
|
ReportDescriptor reportDesc = new ReportDescriptor(); |
|
//Address: EP1IN, Attributes: Interrupt endpoint type, size: 3 bytes, Polling interval: 32ms |
|
EndpointDescriptor endp1inDesc = new EndpointDescriptor(0x81, 0x03, 3, 32); |
|
//Language code |
|
StringDescriptor langIDString = new StringDescriptor(StringDescriptor.LANGID_US_ENG); |
|
//Vendor name |
|
StringDescriptor vendorString = new StringDescriptor("InputStick"); |
|
//Product name |
|
StringDescriptor productString = new StringDescriptor("MyMouse"); |
|
//Serial number |
|
StringDescriptor serialString = new StringDescriptor("SN123"); |
|
//Report descriptor: |
|
reportDesc.usagePage(ReportDescriptor.PAGE_GENERIC_DESKTOP); |
|
reportDesc.usage(ReportDescriptor.DESKTOP_MOUSE); |
|
reportDesc.collection(ReportDescriptor.COLLECTION_APPLICATION); |
|
reportDesc.usage(ReportDescriptor.DESKTOP_POINTER); |
|
reportDesc.collection(ReportDescriptor.COLLECTION_PHYSICAL); |
|
reportDesc.usagePage(ReportDescriptor.PAGE_BUTTON); |
|
reportDesc.usageMinimum(1); |
|
reportDesc.usageMaximum(3); |
|
reportDesc.logicalMinimum(0); |
|
reportDesc.logicalMaximum(1); |
|
reportDesc.reportCount(2); |
|
reportDesc.reportSize(1); |
|
reportDesc.input(ReportDescriptor.DATA | ReportDescriptor.VARIABLE | ReportDescriptor.ABSOLUTE); |
|
reportDesc.reportCount(1); |
|
reportDesc.reportSize(6); |
|
reportDesc.input(ReportDescriptor.CONSTANT); |
|
reportDesc.usagePage(ReportDescriptor.PAGE_GENERIC_DESKTOP); |
|
reportDesc.usage(ReportDescriptor.DESKTOP_X); |
|
reportDesc.usage(ReportDescriptor.DESKTOP_Y); |
|
reportDesc.logicalMinimum(-127); |
|
reportDesc.logicalMaximum(127); |
|
reportDesc.reportSize(8); |
|
reportDesc.reportCount(2); |
|
reportDesc.input(ReportDescriptor.DATA | ReportDescriptor.VARIABLE | ReportDescriptor.RELATIVE); |
|
reportDesc.collectionEnd(); |
|
reportDesc.collectionEnd(); |
|
//Class: HID, Subclass, Protocol: Boot |
|
intDesc.setClass(0x03, 0x01, 0x02); |
|
hidDesc.addReport(Descriptor.DESCRIPTOR_REPORT, reportDesc.getLength()); |
|
|
|
confDesc.addLowLevelDescriptor(intDesc); |
|
confDesc.addLowLevelDescriptor(hidDesc); |
|
confDesc.addLowLevelDescriptor(endp1inDesc); |
|
//setup endpoints |
|
EndpointConfig ep0cfg = new EndpointConfig(USB.ENDPOINT_CONTROL); |
|
EndpointConfig ep1cfg = new EndpointConfig(USB.ENDPOINT_INTERRUPT); |
|
//Endpoint RX state: ready to receive data, Buffer address, Size: 64, Buffer Address: no buffer assigned |
|
ep0cfg.setRXconfig(USB.EP_RX_VALID, 0x18, 0x40, 0); |
|
//Endpoint TX state: stalled, Buffer address, Size: 64, Buffer Address: no buffer assigned |
|
ep0cfg.setTXconfig(USB.EP_TX_STALL, 0x58, 0x40, 0); |
|
//Endpoint RX state: disabled, Buffer address, Size: 0, Buffer Address: no buffer assigned |
|
ep1cfg.setRXconfig(USB.EP_RX_DISABLED, 0x00, 0x00, 0); |
|
//Endpoint TX state: NAK, Buffer address, Size: 3, Buffer Address: no buffer assigned |
|
ep1cfg.setTXconfig(USB.EP_TX_NAK, 0xB0, 0x03, 0); |
|
//setup device data |
|
USBDeviceData devData = super.getDeviceData(); |
|
//Max endpoint index: 2, Number of configurations: 1 |
|
devData.setDeviceInfo(2, 1); |
|
//device is interested in correct transfer and reset events |
|
devData.setImrMsk(USB.CNTR_CTRM | USB.CNTR_RESETM); |
|
//adding data |
|
devData.addEndpoint(ep0cfg); |
|
devData.addEndpoint(ep1cfg); |
|
devData.addDescriptor(devDesc); |
|
devData.addDescriptor(confDesc); |
|
devData.addDescriptor(reportDesc); |
|
devData.addDescriptor(langIDString); |
|
devData.addDescriptor(vendorString); |
|
devData.addDescriptor(productString); |
|
devData.addDescriptor(serialString); |
|
//get buffer for EP1IN |
|
mouseEndp = super.getEndpointBuffer(1); |
|
} |
|
|
|
//press or release left/right button |
|
public void setKeyState(int keyCode, boolean state) { |
|
if (keyCode == 1) { |
|
isLMBPressed = state; |
|
} |
|
if (keyCode == 2) { |
|
isRMBPressed = state; |
|
} |
|
} |
|
|
|
//move mouse pointer by x,y |
|
public void move(int x, int y) { |
|
byte[] report = new byte[3]; |
|
//setup report data |
|
report[0] = 0x00; |
|
report[1] = (byte)x; |
|
report[2] = (byte)y; |
|
if (isLMBPressed) { |
|
report[0] += 1; |
|
} |
|
if (isRMBPressed) { |
|
report[0] += 2; |
|
} |
|
//enqueue USB report, library will manage delivering it to InputStick device as soon as possible |
|
mouseEndp.enqueue(BTCommand.getBytes(BTCommand.CMD_ENDP_IN, BTCommand.ENDP_1, report)); |
|
} |
|
|
|
} |