Skip to content

Instantly share code, notes, and snippets.

Created February 12, 2013 19:05
Show Gist options
  • Save anonymous/4772395 to your computer and use it in GitHub Desktop.
Save anonymous/4772395 to your computer and use it in GitHub Desktop.
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));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment